绑定到在代码嵌套的对象属性后面
问题描述:
嵌套视图模型设置为主窗口的DataContext:绑定到在代码嵌套的对象属性后面
var mainWindow = new MainWindow();
mainWindow.Show();
mainWindow.DataContext = new
{
MyProperty = new
{
MySubProperty = "Hello"
}
}
这是很容易结合到MySubProperty在XAML:
<Button Content="{Binding MyProperty.MySubProperty}"/>
我该怎么办这在代码背后的绑定?
// 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)
{
// ...
}
}
我无法访问MyButton.xaml.cs中的MainWindow,因此我无法将其用作源文件。
按钮只是一个例子,但它将是一个开始。 在我原来的场景中,我没有任何有用的依赖项属性。如果一个dp对于这样一个绑定是必要的,一个例子会非常有帮助,包括创建一个dp。
答
这个怎么样? (只是一个肮脏的例子和未经考验的,原则上应当工作)
// 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)
{
// ...
}
}
编辑:
绑定在代码隐藏的东西,你可以使用:
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);
答
在我原来的问题,我没有依赖属性。所以我创建了一个。
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)
{
// ...
}
}
现在我可以在XAML中设置
<local:MyButton MyStorage="{Binding MyProperty.MySubProperty}"/>
绑定这解决了我的问题。但是我仍然很好奇如何在没有XAML的情况下执行此绑定。
非常感谢您花时间回答。我不知道/我忘了DataContextChanged被调用,如果父母的DataContext被改变。但是,如果数据更加嵌套,编码工作会增加,所以这似乎不是最好的方法。所以我不会将你的答案设定为接受的答案。 – 2010-09-11 12:03:48
@您的编辑:谢谢。但是我没有MyButton类中的MyProperty实例和MainWindow实例。 – 2010-09-11 15:29:37
如果你是绑定的,你可以在DataContext – MrDosu 2010-09-11 16:30:39