在代码中更改绑定模式?

时间:2017-06-29 00:17:25

标签: c# wpf data-binding binding-mode

我正在制作一个小应用程序,它是一个从数据源读取的表单,我想用它来编辑和添加新记录。 所以表单中文本框的默认绑定模式是TwoWay模式,因此用户可以编辑现有记录,但我想添加一个复选框,选中后,它会将文本框中的数据标记为新的,并且然后将它们添加到数据源,所以我需要将绑定模式更改为OneWay, 据我所知,要在代码中执行此操作,我需要创建一个新的Binding对象,我必须设置Source之类的不会更改的属性:

Binding myBinding = new Binding();
myBinding.Source = ViewModel;
myBinding.Path = new PropertyPath("SomeString");
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

那么有没有办法只改变代码中的绑定模式?

修改

对该申请的进一步解释:

在表单中有一个绑定到List<Book>的组合框,有3个TextBox s,它们的Text属性绑定到其容器的DataContext对象上本身设置为SelectedItem的{​​{1}}。 当我按照答案中的描述添加Combobox属性时,当我选中复选框时,我无法更改文本框中的文本。

...

谢谢!

2 个答案:

答案 0 :(得分:1)

不要改变绑定的Mode。只需更正您的视图模型逻辑。

public class ViewModel : INotifyPropertyChanged
{
    private string _text;
    private bool _readOnly;

    public string Text
    {
        get { return _text; }
        set
        {
            if (ReadOnly || value == _text)
                return;

            _text = value;
            OnPropertyChanged(nameof(Text));
        }
    }

    public string ReadOnly
    {
        get { return _readOnly; }
        set
        {
            if (value == _readOnly)
                return;

            _readOnly = value;
            OnPropertyChanged(nameof(ReadOnly));
        }
    }
}

在您的IsCheckedCheckBox属性的XAML绑定ReadOnly属性中。

答案 1 :(得分:-1)

答案是“是的,但是”。 Binding的Mode属性有一个setter。因此,您似乎可以设置现有绑定的模式,如此...

       BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
        Binding b = be?.ParentBinding as Binding;
        if (b != null)
        {
            b.Mode = BindingMode.OneWay;
        }

但是,如果你这样做,你将在每种情况下得到例外......

System.InvalidOperationException occurred
HResult=0x80131509
Message=Binding cannot be changed after it has been used.

因此,实现所需内容的唯一方法是在更改模式时基于旧绑定创建新绑定。然后替换旧的绑定。

           BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
        Binding b = be?.ParentBinding as Binding;
        if (b != null)
        {
            Binding b2 = new Binding();
            b2.Path = b.Path;
            b2.Mode = BindingMode.OneWay;
            textBox.SetBinding(TextBox.TextProperty, b2);
        }

这不太理想,因为为了完整性,您需要复制转换器,转换器参数等,但这是您可以做的最好的。