首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TwoWay MultiBinding

TwoWay MultiBinding
EN

Stack Overflow用户
提问于 2016-03-17 15:05:12
回答 2查看 2.7K关注 0票数 0

MultiBinding

我想要的是:单击任何一个复选框都应该切换所有其他复选框。

问题:单击A不会改变B,单击B不会改变AResult工作。

问题:当我仍然在使用MultiBinding时,我该如何修复它?

P.S.:这是一种解决更复杂的problem的尝试,在提供将所有复选框绑定到单个属性之前,请参考它。

下面是一个mcve

xaml:

代码语言:javascript
复制
<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>

政务司司长:

代码语言:javascript
复制
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

ViewModel:

代码语言:javascript
复制
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(); }
    }
}

转换器:

代码语言:javascript
复制
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();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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中完成,因为所有这些绑定和转换器都使它有点难以跟踪。

票数 0
EN

Stack Overflow用户

发布于 2016-03-17 15:20:19

我想你的转换器应该是这样的

代码语言:javascript
复制
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};
        }
}

然后

代码语言:javascript
复制
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");
            }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36064419

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档