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中将子元素的宽度绑定到父元素的宽度

如何在 C# 中找到 XAML 元素的名称?

如何在不按 Enter C# WPF 的情况下检测我的键盘

如何获取适用于 C# 的 Windows Compact 2013 的 Silverlight 或 XAML?

如何在文件后面没有代码的情况下移动无边框 wpf 窗口

如何在不调用事件的情况下将数据从子级发送到父级(vue 2)