在下面的DataTemplate
中,第一个绑定不起作用,而第二个绑定起作用,我想知道原因。
<local:IsEnabledConverter x:Key="isEnabled"/>
<local:Boolean2TextConverter x:Key="txtConverter"/>
<DataTemplate x:Key="fileinfoTemplate" DataType="{x:Type local:MyFileInfo}">
<StackPanel>
<Label x:Name="1stLabel" Content="{Binding Path=Filename}" IsEnabled="{Binding Path=., Converter={StaticResource isEnabled}}"/> <--- doesn't work
<Label x:Name="2ndLabel" Content="{Binding Path=IfPrint, Converter={StaticResource txtConverter}}" IsEnabled="{Binding Path=IsChecked, ElementName=ckBox}"/> <--- works
<CheckBox x:Name="ckBox" IsChecked="{Binding Path=IfPrint}" IsEnabled="{Binding Path=IsValid}" Style="{StaticResource printCkBox}"/>
</StackPanel>
</DataTemplate>
IsEnabledConverter:
class IsEnabledConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
MyFileInfo f = value as MyFileInfo;
return f.IsValid && f.IfPrint;
}
//... omit ConvertBack NotImplementedException stuff
}
Boolean2TextConverter:
class IsEnabledConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
Boolean b = (Boolean)value;
return b.ToString();
}
//similarly omit ConvertBack here
}
MyFileInfo的代码:
public class MyFileInfo {
public string IfPrint {
get;
set;
}
public string IsValid {
get;
set;
}
...
}
问题:当切换CheckBox
时,第二个Label
会变灰并显示&#34; false&#34;,或者变为正常并显示&#34 ;真实&#34;,应该如此。但是,第一个Label
根本没有变化;它的IsEnabled
状态应该是两个布尔人的联合,其中一个由CheckBox
改变。怎么了? (请注意,IsEnabledConverter
在GUI初始化时调用一次,但在其绑定源更改时不再调用。)
答案 0 :(得分:2)
这里有2个问题。首先,您必须为ViewModel INotifyPropertyChanged
实施MyFileInfo
。其次,你必须在这里使用MultiBinding
。因为如果将整个视图模型绑定到IsEnabled
目标,我认为我们没有办法触发更新目标(例如切换CheckBox时)。所以这是应该如何做的:
您的观看模型:
public class MyFileInfo : INotifyPropertyChanged {
bool _ifPrint;
bool _isValid;
public bool IfPrint {
get { return _ifPrint; }
set {
if(_ifPrint != value) {
_ifPrint = value;
OnPropertyChanged("IfPrint");
}
}
}
public bool IsValid {
get { return _isValid; }
set {
if(_isValid != value) {
_isValid = value;
OnPropertyChanged("IsValid");
}
}
}
//Implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string prop){
var handler = PropertyChanged;
if(handler != null) handler(this, new PropertyChangedEventArgs(prop));
}
//.... should do the same for the remaining properties....
//...
}
以下是MultiBinding
使用的转换器,应该实现IMultiValueConverter
(而不是IValueConverter
):
class IsEnabledConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture) {
if(values.Length == 2){
return (bool) values[0] && (bool) values[1];
}
return false;
}
//... omit ConvertBack NotImplementedException stuff
}
这是修改过的XAML(改为使用MultiBinding):
<Label x:Name="firstLabel" Content="{Binding Path=Filename}">
<Label.IsEnabled>
<MultiBinding Converter="{StaticResource isEnabled}">
<Binding Path="IsValid"/>
<Binding Path="IfPrint"/>
</MultiBinding>
</Label.IsEnabled>
</Label>
现在IsValid
和IfPrint
之一的更改将触发MultiBinding的转换器。在这里,您还可以直接绑定到CheckBox的IsChecked
,而不是通过IfPrint
间接绑定。
PS:注意XAML(以及代码隐藏)中使用的Name
不得以数字开头。
答案 1 :(得分:1)
由于MyFileInfo
的实例在您选中/取消选中checkbox
时未发生更改,因此IsEnabledConverter
未被调用。
要根据两个属性启用/停用1stLabel
,请使用MultiValueConverter
或使用MultiDataTrigger
将样式应用于标签。