使用依赖项属性进行数据绑定

本文关键字:数据绑定 属性 依赖 | 更新日期: 2023-09-27 18:11:57

我是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可能在不同的代码路径更新,我如何确保我的Text1得到更新时,Text2的变化,反之亦然。

TIA。

使用依赖项属性进行数据绑定

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

的例子:Class1 firstClass = new Class1(){propertyName = "Value"};Class1 secondClass = firstClass;

propertyName变量在secondClass中的值现在与firstClass中的值相同。这是因为在内存中对同一个实例有两个引用。如果你使用一个引用来改变它,然后调用另一个引用来获取它的值,你会看到它已经改变了。

编辑:您可以专门创建一个类来保存您希望共享的属性。然后将该类存储为您发布的代码中的一个类的属性。然后引用一个到另一个。
`Class1 class1 = new Class1()
 {
     storage = new StorageClass() { MyProperty = "Hello World" }
 };
 Class2 class2 = new Class2() { storage = class1.storage };`

有两种方法可以实现这种行为。第一个简单的方法是为Class2实现INotifyPropertyChanged,并使用将Mode设置为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,该事件的处理程序可以在属性元数据中设置。这可能看起来像这样,只是分配应该更新的实例:

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