Reputation: 2158
I am trying to bind two properties from two different object that both implements 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 I can bind these two properties in code together something like I would do if one of them was a 'proper' dependency property? Something like this?
ClassA classA = new ClassA();
ClassB classB = new ClassB();
Binding bind = new Binding("Status");
bind.Source = classA;
classB.SetBinding(ClassB.StatusProperty, bind);
Thanks!
Upvotes: 5
Views: 2703
Reputation: 3924
You can't. The property system relies on the registration of a DependencyProperty to attach the binding to. As suggested, you can get around this by monitoring PropertyChanged and handling the changes yourself, but to use bindings in the property system you must use a DependencyProperty.
MSDN states this in the remarks section here.
Upvotes: 0
Reputation: 5117
I ended up having to make one or both a dependency object.
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
Upvotes: 0
Reputation: 3439
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 does this for you with a single method call if you plan to do this often.
Upvotes: 3
Reputation: 671
You can actually create a seperate object with just that property and assign from within your Status Changed classes. If you make it public, both classes should be able to get/set the property.
Upvotes: 0