Caliburn.Micro ItemsSource 未绑定到当前视图模型,而是绑定到父级

Caliburn.Micro ItemsSource is bound not to current viewmodel but to parent

我正在为 WPF 使用 Caliburn.Micro(使用 VS 2012 并面向 .NET 4.5.1)。

我在将 itemsSource 绑定到 ComboBox 时遇到问题(但我调查了在我的情况下它也发生在其他带有 ItemsSource 属性 的控件上,例如 ListBox)。

我有嵌套视图(用户控件)和使用 SimpleContainer (IoC) 创建的视图模型。

这是我的问题:

组合框填充的项目不是来自其视图视图模型 (LanguageSelectionViewModel) 而是来自父视图视图模型 (TopViewModel)。

此外,当我从父视图模型中删除项目集合时,我的组合框是空的。

代码:

MainWindowView.xaml:

<Window
             mc:Ignorable="d"
             d:DesignHeight="300" 
             d:DesignWidth="300"
             d:DataContext="{d:DesignInstance d:Type=mainWindow:MainWindowViewModel}"
         >
    <Grid>
        <top:TopView 

            HorizontalAlignment="Stretch" 
            cal:Bind.Model="{Binding TopVM}" 
            />
          </Grid>
</Window>

MainWindowViewModel:

public class MainWindowViewModel : Screen
{
    private TopViewModel topVm;

    public TopViewModel TopVM
    {
        get { return topVm; }
        set
        {
            topVm = value;
            NotifyOfPropertyChange(() => TopVM);
        }
    }

    public MainWindowViewModel(TopViewModel topVm, ContentViewModel contentVm)
    {
        TopVM = topVm;
        TopVM.ConductWith(this);
    }
}

TopView.xaml:

<UserControl>
   <StackPanel Orientation="Horizontal">
      <languageSelection:LanguageSelectionView cal:Bind.Model="{Binding LanguageSelectionVM}"/>
   </StackPanel>
</UserControl>

TopViewModel.cs:

public class TopViewModel : Screen
{
    private LanguageSelectionViewModel _languageSelectionVM;

    public LanguageSelectionViewModel LanguageSelectionVM
    {
        get { return _languageSelectionVM; }
        set
        {
            _languageSelectionVM = value;
            NotifyOfPropertyChange(() => LanguageSelectionVM);
        }
    }

    public TopViewModel(ClockViewModel clockVm, LanguageSelectionViewModel languageSelectionVM)
    {
        this.Items = new ObservableCollection<string>() { "a", "a", "a" };

        LanguageSelectionVM = languageSelectionVM;
        LanguageSelectionVM.ConductWith(this);
    }

    private ObservableCollection<string> _items;

    public ObservableCollection<string> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            NotifyOfPropertyChange(() => Items);
        }
    }

}

LanguageSelectionView.xaml:

<UserControl>
    <StackPanel Orientation="Vertical">
        <ComboBox ItemsSource="{Binding Items}"/>
    </StackPanel>
</UserControl>

LanguageSelectionViewModel.cs:

public class LanguageSelectionViewModel : Screen
{
    private ObservableCollection<string> _items;

    public ObservableCollection<string> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            NotifyOfPropertyChange(() => Items);
        }
    }

    public LanguageSelectionViewModel()
    {
        this.Items = new ObservableCollection<string>() { "1", "a" };
    }
}

稍后我也尝试填充此集合,但没有成功:

    protected override void OnViewReady(object view)
    {
        base.OnViewReady(view);
        this.Items = new ObservableCollection<string>() { "1", "a" };
        Refresh();
    }

DataContext 似乎没问题,因为绑定到文本框

<TextBlock Text="{Binding TestString}"/>

工作正常。

我发现 ComboBox 是唯一将 DataContext 设置为父视图模型的控件,而不是正确的视图模型。

它通过以这种方式强制它来工作:

<ComboBox 
         DataContext="{Binding}"
         ItemsSource="{Binding Items}" >

但问题仍然存在 - 为什么?这是 Caliburn.Micro?

的错误或功能

好了,谜底解开了。

而不是像这样嵌套控件:

  <Grid>
     <top:TopView 
        cal:Bind.Model="{Binding TopVM}" />
  </Grid>

我应该写:

  <Grid>
     <ContentControl
        cal:View.Model="{Binding TopVM}" />
  </Grid>

而且不需要强制 DataContext。