双向多重绑定 [英] TwoWay MultiBinding

查看:126
本文介绍了双向多重绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MultiBinding:

我想要的是:单击任一复选框应切换所有其他复选框.

What I want: clicking either checkbox should toggle all others.

问题:单击A不会更改B,单击B不会更改A. Result有效.

Problem: clicking A doesn't change B, clicking B doesn't change A. Result works.

问题:在仍使用MultiBinding的情况下如何解决?

Question: how would I fix it, while still using MultiBinding?

PS:这是试图解决更复杂的问题的尝试,在提供将所有复选框绑定到一个属性.

P.S.: this is an attempt to solve more complicated problem, please refer to it before offering to bind all checkboxes to a single property.

下面是一个 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>

cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

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();
}

推荐答案

简单的原因是,当您单击CheckBox A 时,将永远不会调用ConvertBack()方法.

The simple reason is, the ConvertBack() method will never be called when you click CheckBox A.

请考虑以下原因:

Checkbox A 得到检查.

<Binding />调用Property-Setter A .

<Binding /> calls Property-Setter A.

资产设定者 A 被呼叫.

财产设定者 A 呼叫OnPropertyChanged("A").

PropertyChanged-Event由CheckBox 结果<MultiBinding />接收.

PropertyChanged-Event is recieved by the <MultiBinding /> of CheckBox Result.

属性键 A B .

MultiBindingConverter.Convert()方法.

<MultiBinding />更新视图中的CheckBox 结果 IsChecked状态.

<MultiBinding /> updates the CheckBox Result IsChecked state in the view.

无需触摸CheckBox B并仅调用属性 B 的获取方法即可完成更改.

Handling of change is done without ever touching CheckBox B and only calling the getter of property B.

如果所有CheckBox上都有一个MultiBinding,则将调用所有适当的设置器.但是,如果每个CheckBox的更改行为都不同,则可能需要实现一个不同的Converter.

If you have a MultiBinding on all CheckBoxes, then all appropriate setters will be called. You might need to implement a different Converter though, if the change behaviour should be different for each CheckBox.

这也是原因,如果可能的话,最好在ViewModel中最好进行这样的更改,因为所有这些Bindings和Converters使得跟踪变得有些困难.

That is also the reason, why changing stuff like that should - preferably - be done within the ViewModel if possible, because all those Bindings and Converters make it a little hard to track.

这篇关于双向多重绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆