Caliburn.Micro ItemsSource不是绑定到当前的viewmodel而是绑定到parent

时间:2015-05-27 11:22:15

标签: c# wpf xaml data-binding caliburn.micro

我使用Caliburn.Micro for WPF(使用VS 2012并定位到.NET 4.5.1)。

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

我有使用SimpleContainer(IoC)创建的视图模型的嵌套视图(usercontrols)。

这是我的问题:

Combobox中的项目不是来自其视图viewmodel (LanguageSelectionViewModel),而是来自父视图viewmodel (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}"/>

工作正常。

2 个答案:

答案 0 :(得分:1)

好的,神秘解决了。

而不是像这样嵌套控件:

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

我应该写:

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

并且无需强制使用DataContext。

答案 1 :(得分:0)

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

它的工作原理是这样:

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

但问题仍然存在 - 为什么?这是Caliburn.Micro的错误或特征吗?