玩MultiBinding

我想要的是:单击任何一个复选框都应该切换所有其他复选框。
问题:单击A不会改变B,单击B不会改变A。Result工作。
问题:当我仍然在使用MultiBinding时,我该如何修复它?
P.S.:这是一种解决更复杂的problem的尝试,在提供将所有复选框绑定到单个属性之前,请参考它。
下面是一个mcve。
xaml:
<StackPanel>
<CheckBox Content="A" IsChecked="{Binding A}" />
<CheckBox Content="B" IsChecked="{Binding B}" />
<CheckBox Content="Result">
<CheckBox.IsChecked>
<MultiBinding Converter="{local:MultiBindingConverter}">
<Binding Path="A" />
<Binding Path="B" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</StackPanel>政务司司长:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}ViewModel:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
bool _a;
public bool A
{
get { return _a; }
set { _a = value; OnPropertyChanged(); }
}
bool _b;
public bool B
{
get { return _b; }
set { _b = value; OnPropertyChanged(); }
}
}转换器:
public class MultiBindingConverter : MarkupExtension, IMultiValueConverter
{
public MultiBindingConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider) => this;
object[] _old;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// first time init
if (_old == null)
_old = values.ToArray();
// find if any value is changed and return value
for (int i = 0; i < values.Length; i++)
if (values[i] != _old[i])
{
_old = values.ToArray();
return values[i];
}
// if no changes return first value
return values[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
Enumerable.Repeat(value, targetTypes.Length).ToArray();
}发布于 2017-08-08 14:17:06
原因很简单,当您单击ConvertBack() A时,将永远不会调用该方法。
考虑以下理由:
Checkbox A被检查。
<Binding />调用Property-Setter A.
属性-设置器调用。
属性-设置器调用OnPropertyChanged("A")。
PropertyChanged-事件由<MultiBinding /> of CheckBox 接收。
属性获取器A、和B (仍未更改)正在被调用。
绑定调用MultiBindingConverter.Convert()方法。
<MultiBinding />更新视图中的CheckBox 结果 IsChecked状态。
更改的处理是在没有接触CheckBox B的情况下完成的,并且只调用属性的getter of B。
如果您在所有的MultiBinding es上都有一个CheckBox,那么将调用所有适当的setter。但是,如果每个CheckBox的更改行为不同,则可能需要实现不同的转换器。
这也是为什么这样的改变应该--最好是--如果可能的话,应该在ViewModel中完成,因为所有这些绑定和转换器都使它有点难以跟踪。
发布于 2016-03-17 15:20:19
我想你的转换器应该是这样的
public class MultiBindingConverter : MarkupExtension, IMultiValueConverter
{
public MultiBindingConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider) => this;
object[] _old;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)values[0] /*A */) || ((bool)values[1]/* B */);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[] { (bool)value, (bool)value};
}
}然后
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
bool _a;
public bool A
{
get { return _a || _b; }
set {
if (_a == value) return;
_a = value;
OnPropertyChanged("A");
OnPropertyChanged("B");
}
}
bool _b;
public bool B
{
get { return _b || _a; }
set {
if (_b == value) return;
_b = value;
OnPropertyChanged("B");
OnPropertyChanged("A");
}
}
}https://stackoverflow.com/questions/36064419
复制相似问题