在两个对象的属性之间绑定,这两个对象都在代码中实现INotifyPropertyChanged

时间:2012-03-30 16:17:34

标签: .net wpf binding

我正在尝试绑定来自两个不同对象的两个属性,这两个对象都在代码中实现INotifyPropertyChanged

    public class ClassA : INotifyPropertyChanged
    {
        // leaving out the INotifyPropertyChanged Members for brevity

        public string Status
        {
            get { return _Status; }
            set { _Status = value; RaiseChanged("Status"); }
        }

    }

    public class ClassB : INotifyPropertyChanged
    {
        // leaving out the INotifyPropertyChanged Members for brevity

        public string Status
        {
            get { return _Status; }
            set { _Status = value; RaiseChanged("Status"); }
        }

    }

有没有办法可以将代码中的这两个属性绑定在一起,如果其中一个属性是“正确的”依赖属性,我会怎么做? 像这样的东西?

ClassA classA = new ClassA();
ClassB classB = new ClassB();

Binding bind = new Binding("Status");
bind.Source = classA;
classB.SetBinding(ClassB.StatusProperty, bind);

谢谢!

4 个答案:

答案 0 :(得分:2)

迟到的反应,但是... KISS:

ClassA classA = new ClassA();
ClassB classB = new ClassB();

classA.PropertyChanged += (s, e) => {
    if (e.PropertyName == "Status")
        classB.Status = classA.Status;
};

Voila,INPC对象之间的“绑定”:)如果您打算经常这样做,您可以轻松地创建一个非常简单的帮助程序类,通过单个方法调用为您执行此操作。

答案 1 :(得分:0)

您实际上可以使用该属性创建一个单独的对象,并从Status Changed类中进行分配。如果你公开,两个类都应该能够获得/设置属性。

答案 2 :(得分:0)

我最终不得不创建一个或两个依赖对象。

XAML:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Text="{Binding Path=Obj1.Status}"/>
        <TextBox Text="{Binding Path=Obj2.Status}"/>
    </StackPanel>
</Window>

代码:

Class MainWindow
    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Me.DataContext = New SomeViewModel
    End Sub
End Class

Public Class SomeViewModel
    Implements ComponentModel.INotifyPropertyChanged

    Protected _Obj1 As SomeClass
    Public ReadOnly Property Obj1 As SomeClass
        Get
            Return _Obj1
        End Get
    End Property
    Protected _Obj2 As SomeClass
    Public ReadOnly Property Obj2 As SomeClass
        Get
            Return _Obj2
        End Get
    End Property

    Public Sub New()
        _Obj1 = New SomeClass
        _Obj2 = New SomeClass
        NotifyPropertyChanged("Obj1")
        NotifyPropertyChanged("Obj2")

        Dim StatusBinding As New Binding("Status") With {.Source = Obj2, .Mode = BindingMode.TwoWay}
        BindingOperations.SetBinding(Obj1, SomeClass.StatusProperty, StatusBinding)
    End Sub

    Private Sub NotifyPropertyChanged(<Runtime.CompilerServices.CallerMemberName()> Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs(propertyName))
    End Sub
    Public Event PropertyChanged(sender As Object, e As ComponentModel.PropertyChangedEventArgs) Implements ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class

Public Class SomeClass
    Inherits DependencyObject
    Implements ComponentModel.INotifyPropertyChanged

    Public Shared ReadOnly StatusProperty As DependencyProperty = DependencyProperty.Register(name:="Status", propertyType:=GetType(String), ownerType:=GetType(SomeClass), typeMetadata:=New PropertyMetadata(propertyChangedCallback:=AddressOf OnDependencyPropertyChanged))

    Private Shared Sub OnDependencyPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
        d.SetValue(e.Property, e.NewValue)
    End Sub

    Protected _Status As String
    Public Property Status As String
        Set(value As String)
            If value <> Me._Status Then
                Me._Status = value
                NotifyPropertyChanged()
            End If
        End Set
        Get
            Return _Status
        End Get
    End Property

    Private Sub NotifyPropertyChanged(<Runtime.CompilerServices.CallerMemberName()> Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs(propertyName))
    End Sub
    Public Event PropertyChanged(sender As Object, e As ComponentModel.PropertyChangedEventArgs) Implements ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class

答案 3 :(得分:0)

你不能。属性系统依赖于DependencyProperty的注册来附加绑定。如建议的那样,您可以通过监视PropertyChanged并自己处理更改来解决这个问题,但是要在属性系统中使用绑定,您必须使用DependencyProperty。

MSDN在备注部分here中说明了这一点。