我正在尝试绑定2维列表,在屏幕上将其显示为CheckBox
es的矩阵。绑定似乎工作一次(当显示窗口时)。它还更新源。但是源中的更改不会导致更新UI。
我的ViewModel具有这样的属性(它不一定是propdp
,因为列表没有改变,只有项目,对吧?):
public BindingList<BindingList<ViewModelPageBase>> Pages { get; private set; }
public ViewModelMainWindow()
{
var page1 = new BindingList<ViewModelPageBase>();
page1.Add(new ViewModelPageSettings() { IsSelected = true });
page1.Add(new ViewModelPageProfile());
...
var page2 = new BindingList<ViewModelPageBase>();
page2.Add(new ViewModelPageAnalyse() { IsSelected = true });
...
Pages = new BindingList<BindingList<ViewModelPageBase>>(new[] { page1, page2, ... });
}
public class ViewModelPageBase : ViewModelBase
{
public string Caption { get; protected set; } // will be set in constructor of inherited page
public bool IsSelected { get; set; }
}
正如您所看到的那样,这是一个简单的List<List<T>>
。我尝试了ObservableCollection
和BindingList
他们都说了问题。
然后我有一个propdp
Items
的自定义控件和
<ItemsControl ItemsSource="{TemplateBinding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<ItemContainerTemplate>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<ItemContainerTemplate>
<CheckBox Content="{Binding Caption}" IsChecked="{Binding IsSelected}"/>
</ItemContainerTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ItemContainerTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在窗口绑定中看起来像这样
<local:NavigatorMap Items="{Binding Pages}"/>
所有人说产生这个结果
当窗口出现时,单击复选框更新IsSelected
没有问题,以编程方式设置IsSelected
不会更新复选框。
我做错了什么?为什么Pages
中的更改不会导致UI中的自动更新?它更像是Mode.OneTime
和Mode.OneWayToSource
的组合。我期待Mode.TwoWay
(我实际上需要Mode.OneWay
)。在所有地方明确指定TwoWay
不会做任何事情。
答案 0 :(得分:1)
但源中的更改并未导致更新UI。
这是因为ViewModel的属性不会引发PropertyChanged
事件。确保您的类实现INotifyPropertyChanged
,并更改如下属性:
public class ViewModelPageBase : ViewModelBase
{
private string _caption;
public string Caption
{
get { return _caption; }
protected set // will be set in constructor of inherited page
{
if (value != _caption)
{
_caption = value;
OnPropertyChanged("Caption");
}
}
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value != _selected)
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
}