C#如何在没有 XAML 的情况下创建到父元素的(两种方式)数据绑定
Posted
技术标签:
【中文标题】C#如何在没有 XAML 的情况下创建到父元素的(两种方式)数据绑定【英文标题】:C# How do I create a (two way) databinding to Parent Elements WITHOUT XAML 【发布时间】:2021-01-05 14:59:31 【问题描述】:我正在尝试列出我的 PropertyEntry 类(用户控件),它是为 Person 类的每个属性生成的。遗憾的是,互联网上的大多数指南只告诉您如何通过 XAML 文件创建绑定,但我需要一个可以在没有它的情况下通用的解决方案。所以这是我已经完成的工作:
public partial class PropertyEntry : UserControl
public PropertyEntry(string propertyName)
Binding propertyBinding = new Binding(); // <--- How do I setup a two-way binding to the PersonToEdit property of the ancestor
InitializeComponent();
this.PropertyLabel.Content = labelName + ": ";
this.PropertyInput.SetBinding(); // <--- How do I apply this binding to my Input
这里是直系祖先:
public partial class PersonView : Window
public Person PersonToEdit get; set;
public PersonView(Person person)
PersonToEdit = person;
InitializeComponent();
public void updateUserControlByUniqueClassFields(object sender, SelectionChangedEventArgs e)
PropertyInfo[] varyingPropeties = findVaryingFields();
varyingPropeties.ToList().ForEach((property) =>
PropertyList.Children.Add(new PropertyEntry(property.Name)); //<--- Stackpanel
);
... more code
我想指出,Person 类已经实现了 IPropertyNotificator,因此我可以稍后将 OnPropertyChanged 事件分配给 UpdateSourceTrigger。我只想知道如何通过代码为这种场景组装一个合适的绑定,因为我不知道如何访问祖先来正确设置新的绑定。
编辑:我正在使用 C# WPF 到目前为止,我设法创建了一个 Binding,它似乎绑定到了正确的实例,但仍然没有正确地将属性显示为 TextBox.Text。
public partial class PropertyEntry : UserControl
public PropertyEntry(Person dataSourceToBind, string propertyName)
Binding propertyBinding = new Binding();
propertyBinding.Source = dataSourceToBind;
propertyBinding.Path = new PropertyPath(propertyName);
propertyBinding.Mode = BindingMode.TwoWay;
propertyBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
InitializeComponent();
this.PropertyLabel.Content = propertyName;
this.PropertyInput.SetBinding(TextBlock.TextProperty, propertyBinding);
dataSourceToBind.OnPropertyChanged(propertyName);
EDIT2:我找到了解决方案并想与大家分享。也许其他人也会有同样的困难,并且网络上没有太多关于这个问题的代码。所以行:
this.PropertyInput.SetBinding(TextBlock.TextProperty, propertyBinding);
必须是
BindingOperations.SetBinding(PropertyInput, TextBox.TextProperty, propertyBinding);
改为。
【问题讨论】:
【参考方案1】:能否请您说明您使用的是 WPF、UWP、WinForms 吗?请注意,解决方案可能会因您使用的设备而异。
假设您使用的是 WPF,这应该会让您朝着正确的方向前进:
propertyBinding.Mode = BindingMode.TwoWay;
// from the MS Example for a TextBlock binding
BindingOperations.SetBinding(myDateText, TextBlock.TextProperty, myNewBindDef);
BindingOperations.SetBinding(myDateText, TextBlock.ForegroundProperty, myNewBindDef);
请查看这些网站以获取有关在代码中执行此操作的更多信息:
https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/binding-declarations-overview?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-5.0 https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/data-binding-overview?view=netdesktop-5.0【讨论】:
是的,对不起。忘了提到我正在使用WPF。我遇到的问题是,如果您执行新的绑定(路径),您实际上必须指定一个路径。由于我要绑定的属性是“PersonToEdit”并且是 PersonView 的一部分,因此我不确定如何为其正确设置正确的路径,因为它不是 PropertyEntry UserControll 的一部分。以上是关于C#如何在没有 XAML 的情况下创建到父元素的(两种方式)数据绑定的主要内容,如果未能解决你的问题,请参考以下文章
如何在silverlight中将子元素的宽度绑定到父元素的宽度