项目场景:
有两个控件CheckBox1
和CheckBox2
,2的IsSelected
需要既与1的该属性一致,又与它的DataContext内的对象Node的IsSelected属性一致,因此我想到了使用MultiBinding
Node对象结构:
public class Node : INotifyPropertyChanged
{
public Node(string szFatherNodeName = "")
{
IsSelected = false;
}
/// <summary>
/// 是否被选中
/// </summary>
private bool? isSelected = false;
public bool? IsSelected
{
get { return this.isSelected; }
set
{
this.isSelected = value;
this.OnPropertyChanged();
}
}
}
Xaml:
<CheckBox x:Name="chk1" />
<CheckBox Background="Transparent" Content="{Binding Path=NodeName}" VerticalAlignment="Center" HorizontalAlignment="Left">
<CheckBox.IsEnabled>
<MultiBinding Converter="{StaticResource MultiSelectedValueConverter}">
<Binding ElementName="chk1" Path="IsChecked" Mode="OneWay"/>
<Binding Path="IsSelected" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</CheckBox.IsEnabled>
</CheckBox>
Converter类
public class MultiSelectedValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
//此处打断点
;
return new object[2] { value, value };
}
}
问题描述
运行时发现chk2
的IsChecked
随chk1
变化而变化,但不能影响到IsSelect属性,我在ConverterBack
方法处打断点,发现ConverterBack
方法压根没有调用。
开始我以为是CheckBox
绑定时获取值变化的机制不一样,比如TextBox
它默认的就UpdateSourceTrigger
是LostFocus
即失去焦点时通知被绑定对象,需要手动改为PropertyChanged
,于是我用TextBox
试了一下,又用CheckBox
的IsEnabled
属性试了一下,不管怎么更改UpdateSourceTrigger
,都无法进入断点,无法实时回传到绑定的Source的IsSelect属性。
原因分析:
分析认为这种做法逻辑上就有错误,multibinding即使看起来是双向的,实际上也是有先后的,multi的多个条件发生在前(即使是像我的例子里面OneWayToSource),Target的结果在后,想要Source随之更改,必须是其他外界影响使Target发生更改。否则如果是双向绑定,没道理Source自已产生的改变影响了Target又马上影响回Source,这样岂不是一直在循环了。
解决方案:
暂时没有找到办法,只能放弃使用绑定,改为事件触发