使用依赖属性的数据绑定

时间:2016-10-06 14:50:33

标签: c# data-binding dependency-properties

我是C#的新手并且玩弄依赖属性。我有一个天真的场景,我希望类的属性绑定到另一个类的属性。我想要它们之间的双向数据绑定。

Class1{
        public string Text1
        {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
        }
        public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text1", typeof(string), typeof(Class1),
            new PropertyMetadata(true));
 }

Class2{
        public string Text2
        {
        get{;}
        set{;}
        }
}

Text1和Text2可能会在不同的代码路径中更新,如何确保Text2在Text2更改时更新,反之亦然。

TIA。

2 个答案:

答案 0 :(得分:0)

我的理解是,这不能用值类型(int,string等)来完成,但可以使用引用类型(例如您创建的类)来完成。

实施例:  Class1 firstClass = new Class1(){propertyName =“Value”};  Class1 secondClass = firstClass;

secondClass中propertyName变量的值现在与firstClass中的值相同。这是因为您在内存中有两个对同一实例的引用。如果您使用一个引用更改它并调用以获取另一个引用的值,您将看到它已更改。

编辑:您可以专门创建一个类来保存您想要共享的属性。然后将该类存储为您发布的代码中的一个类的属性。然后只引用一个到另一个。

`Class1 class1 = new Class1()
 {
     storage = new StorageClass() { MyProperty = "Hello World" }
 };

 Class2 class2 = new Class2() { storage = class1.storage };`

对一个人所做的任何更改现在都会改变另一个。

答案 1 :(得分:0)

有两种方法可以实现此行为。第一个也是最简单的方法是为Class2实现INotifyPropertyChanged,并使用模式设置为Two Way的Bindings。这可确保绑定的实例中的两个属性始终具有相同的值。例如:

class Class1 : DependencyObject {
    public string Text1 {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text1", typeof(string), typeof(Class1),
        new PropertyMetadata(true));
}

class Class2 : INotifyPropertyChanged {
    private string _text2;

    public string Text2 {
        get { return _text2; }
        set {
            if (value == _text2) return;
            _text2 = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后像这样设置你的绑定:

var class1 = new Class1();
var class2 = new Class2();

var binding = new Binding();
binding.Path=new PropertyPath("Text2");
binding.Source = class2;
binding.Mode=BindingMode.TwoWay;
binding.UpdateSourceTrigger= UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(class1, Class1.TextProperty, binding);

另一个更脏的解决方案是在属性旁边存储相应其他类的实例。在Text2中,您可以通过存储的实例更改Text1,Text1可以通过OnValueChanged事件更改Text2,该事件的处理程序可以在Property Metadata中设置。这看起来像这里,只是分配应该更新的实例:

class Class1 : DependencyObject {
    public Class2 OtherInstance { get; set; }

    public string Text1 {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text1", typeof(string), typeof(Class1),
        new PropertyMetadata(true, (o, args) => ((Class1)o).OtherInstance.Text2 = (string)args.NewValue));
}

class Class2 {
    private string _text2;

    public Class1 OtherInstance { get; set; }

    public string Text2 {
        get { return _text2; }
        set {
            _text2 = value;
            OtherInstance.Text1 = value;
        }
    }
}