Linking between properties of two objects that implement INotifyPropertyChanged in code

I am trying to link two properties from two different objects that are implemented INotifyPropertyChanged

in code:

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

    }

      

Is there a way to link these two properties together in code, something like what I would do if one of them was a "proper" dependency property? Something like that?

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

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

      

Thank!

+3


source to share


4 answers


Late response, but ... KISS:

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

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

      



Voila, "binding" between INPC objects :) You can easily create a very simple helper class that will do this for you in one method call if you plan on doing this often.

+1


source


In fact, you can create a separate object with just this property and assign it in classes with changed status. If you make it public, both classes should be able to get / set the property.



0


source


I had to make one or both of the dependency objects.

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>

      

code:

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

      

0


source


You can not. The property system relies on registering a DependencyProperty to bind the binding. As suggested, you can work around this by controlling the PropertyChanged and handling the changes yourself, but you must use a DependencyProperty to use bindings in the property system.

MSDN states this in the notes section here .

0


source







All Articles