Binding to property in nested objects in code behind
The nested ViewModel is set to the MainWindow DataContext:
var mainWindow = new MainWindow();
mainWindow.Show();
mainWindow.DataContext = new
{
MyProperty = new
{
MySubProperty = "Hello"
}
}
It is easy to bind to MySubProperty in XAML:
<Button Content="{Binding MyProperty.MySubProperty}"/>
How can I do this binding in code behind?
// MyButton.xaml.cs
public partial class MyButton : Button
{
public MyButton()
{
InitializeComponent();
// todo: add binding here
}
// I want this method called if this datacontext is set.
// and called if MySubProperty changes and INotifyPropertyChange is implemented in the Datacontext.
public void MySubPropertyChanged(string newValue)
{
// ...
}
}
I have no a开发者_Go百科ccess to MainWindow in MyButton.xaml.cs, so I cannot use it as a source.
The Button is just an example, but it would be a start. In my original scenario I have no useful dependency property for that. If a dp is necessary for such a binding, an example would be very helpful that includes the creation of a dp.
How about this? (just a dirty example and untested, should work in principle)
// MyButton.xaml.cs
public partial class MyButton : Button
{
public MyButton()
{
InitializeComponent();
this.DataContextChanged += DataContext_Changed;
}
private void DataContext_Changed(Object sender,DependencyPropertyChangedEventArgs e)
{
INotifyPropertyChanged notify = e.NewValue as INotifyPropertyChanged;
if(null != notify)
{
notify.PropertyChanged += DataContext_PropertyChanged;
}
}
private void DataContext_PropertyChanged(Object sender,PropertyChangedEventArgs e)
{
if(e.PropertyName == "MySubProperty")
MySubPropertyChanged((sender as YourClass).MySubProperty);
}
public void MySubPropertyChanged(string newValue)
{
// ...
}
}
EDIT:
for binding something in codebehind you can use:
Binding binding = new Binding();
// directly to myproperty
binding.Source = MyProperty;
binding.Path = new PropertyPath("MySubProperty");
// or window
binding.Source = mainWindow; // instance
binding.Path = new PropertyPath("MyProperty.MySubProperty");
// then wire it up with (button is your MyButton instance)
button.SetBinding(MyButton.MyStorageProperty, binding);
//or
BindingOperations.SetBinding(button, MyButton.MyStorageProperty, binding);
In my original problem I had no dependency Property. So I created one.
public partial class MyButton : Button
{
//...
public string MyStorage
{
get { return (string)GetValue(MyStorageProperty); }
set { SetValue(MyStorageProperty, value); }
}
public static DependecyProperty MyStorageProperty =
DependencyProperty.Register("MyStorage", typeof(string), typeof(MyButton),
new UIPropertyMetadata(OnMyStorageChanged));
public static void OnMyStorageChanged(DependecyObject d, DependencyPropertyChangedEventArgs e)
{
var myButton = d as MyButton;
if (myButton == null)
return;
myButton.OnMyStorageChanged(d,e);
}
public void OnMyStorageChanged(object sender, DependencyPropertyChangedEventArgs e)
{
// ...
}
}
And now I can set the Binding in XAML
<local:MyButton MyStorage="{Binding MyProperty.MySubProperty}"/>
This solved my problem. But I’m still curious how to do this binding without XAML.
精彩评论