所以我现在正在学习WPF,并希望在bool值之间做一个简单的数据绑定,以及是否启用了MenuItem
。
我的编码是这样的:
<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click"
IsEnabled="{Binding}" />
在我设置的.cs文件中:
miSaveFile.DataContext = dataChanged;
由于某种原因,MenuItem
似乎没有正确反映dataChanged的状态。
我错过了什么?
答案 0 :(得分:4)
最好绑定到对象而不是原始类型。此对象通常被称为视图的“模型”。
WPF使用INotifyPropertyChanged接口为模型(或通常是视图模型)通知视图模型已更改状态。
因此,您首先要将数据类定义为实现INotifyPropertyChanged接口的模型,并在属性发生更改时触发PropertyChanged事件。
设置绑定时,您需要担心绑定上的5个主要元素。绑定具有源对象,源对象上的源路径,目标对象,目标对象上的目标属性以及可选的转换器。
如果未指定源,则默认为设置绑定的控件的DataContext。还有其他设置源的选项。 Here是一篇关于设置源代码的Microsoft文章。然后,您可以设置属性的路径以从绑定源中拉出。在您的情况下,源是布尔值,没有路径,因为绑定使用整个源对象。
目标始终是您设置绑定的控件,而target属性是您绑定到此控件的属性。在这种情况下,MenuItem和IsEnabled。
转换器可以选择将源值转换为与target属性兼容的值。您可以将任何对象用于实现IValueConverter或IMultiValueConverter的转换器(用于MutliBindings)。
在您的情况下,我将首先创建一个实现INotifyPropertyChanged的模型。接下来,我将菜单的DataContext分配给模型的实例。然后我将绑定设置为:
IsEnabled="{Binding Path=EnableFlag}"
(其中EnableFlag是您想要菜单绑定到的模型中的布尔属性)
如果正确设置了INotifyPropertyChanged接口,只要在模型上更改此属性,就会启用/禁用菜单项。
答案 1 :(得分:2)
对于MenuItem,使用Command模型而不是Click和IsEnabled属性是不是更好的方法?
在InitialiseComponent()之后:
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save, fileSaveExecuted, fileSaveCanExecute));
其他方法:
/* here is where you set e.CanExecute true for enabled: */
private void fileSaveCanExecute(object x, CanExecuteRoutedCommandEventArgs e)) { e.CanExecute = ...; e.Handled = true; }
/* here is where you act on the command: */
private void fileSaveExecuted(object sender, ExecutedRoutedEventArgs e) { ... }
XAML:
<MenuItem Header="_Save" Command="Save"/>
答案 2 :(得分:1)
UI如何知道dataChanged变量何时实际发生变化?
我通常绑定到对象上的属性,并让该类实现INotifyPropertyChanged。然后,只要调用PropertyChanged事件,就会“自动”更新UI。
所以我会
<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click"
IsEnabled="{Binding DataChanged}"</MenuItem>
然后设置miSaveFile.DataContext = myObject.DataChanged (如果使用代码隐藏,myObject可以是这个)
编辑:我刚做了一个快速测试。如果将数据上下文直接设置为DataChanged属性,则不会添加对所有者对象上的PropertyChanged事件的预订。但我建议的解决方案有效。