gpt4 book ai didi

c# - 将简单绑定(bind)到“文本属性”的解决方案扩展到多个控件以处理与任何类型的绑定(bind)?

转载 作者:行者123 更新时间:2023-11-30 16:34:38 25 4
gpt4 key购买 nike

我的问题是:如何超越编写数据绑定(bind)多个控件(没有内置 DataSource 属性的控件)技术的自定义实现,针对每种可能的数据类型,到简单的属性......如后面的代码中所述和演示的那样......实现更强大的解决方案,无论绑定(bind)是字符串还是 int,或其他类型。

我的猜测是:这将涉及反射(reflection);但是,我被困在这一点上。我正在寻找关于下一步移动“方向”的战略建议,提示,线索,而不是完整的代码答案,但当然我感谢所有回复,如果您发布代码作为回复,我一定会研究代码! Marc Clifton 2005 年关于 CodeProject 的文章 Simple Databinding : 似乎展示了一种基于反射的方法:但是,老实说,我并没有真正理解他的代码,而且,就 .NET 而言,2005 年是很久以前的了。

背景:部分是为了回应各种 SO 问题和答案,例如:Update Usercontrol on Three Forms :我已经发展出一种成功的技术,可以将各种控件的文本属性同时数据绑定(bind)到公共(public)类中定义的一个源;还能够使用定义一个扩展方法和两个公共(public)方法的静态类来“抽象”绑定(bind)过程的一些细节。

我已经验证了“主窗体”中控件上的文本框、主窗体上用户控件上的文本框以及“独立”打开的第二个窗体上的文本框(即 form2.Parent == null)所有更新正确(即,双向绑定(bind)有效)来自“DataSource equivalent”公共(public)类。改一:全部改。

代码:此类的实例将为数据绑定(bind)提供目标属性 (theText):

    public class TextDataBinder
{
public event PropertyChangedEventHandler PropertyChanged;

private string _theText;

public string theText
{
get { return _theText; }

// note : if 'setter is declared 'internal : blocks
// auto-updating when run-time user modifies consumers
// but will still allow update via code
set
{
_theText = value;
OnPropertyChanged(new PropertyChangedEventArgs("theText"));
}
}

protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, e);
}
}
}

代码:这个静态类可以隐藏一些绑定(bind)过程的复杂性,并允许轻松绑定(bind)到多个控件:

    public static class TextBindingExtender
{
public static TextDataBinder CurrentDataSource;

public static void SetCurrentDataSource(TextDataBinder newCurrentDataSource)
{
CurrentDataSource = newCurrentDataSource;
}

// extension method for Control
public static void AddTextBinding(this Control theControl, string controlPropertyName, string targetPropertyName)
{
theControl.DataBindings.Add(controlPropertyName, CurrentDataSource, targetPropertyName, false, DataSourceUpdateMode.OnPropertyChanged);
}

// bind to all Controls in a List<Control>
public static void AddTextBindings(List<Control> theControls, string controlPropertyName, string targetPropertyName)
{
foreach (Control theControl in theControls)
{
theControl.AddTextBinding(controlPropertyName, targetPropertyName);
}
}
}

如何使用上述类(在 Form Load 事件中):

    // create a new TextDataBinder
TextBindingExtender.CurrentDataSource = new TextDataBinder();

// bind to multiple textboxes, label, on a UserControl, on another Form, etc.
TextBindingExtender.AddTextBindings(new List<Control> { textBox1, textBox2, userControl11.tb, label1, instanceOfForm2.tb }, "Text", "theText");

// test assigning some initial text to the bound property
TextBindingExtender.CurrentDataSource.theText = "some initial text";

最佳答案

这真的取决于你想做什么;但最终常见的数据绑定(bind)(对于简单的属性,手动完成)包括:

  • 获得属性(property);最好通过 TypeDescriptor.GetProperties(obj)[propName],为您提供抽象 (PropertyDescriptor)
  • 询问属性是否为只读 (.IsReadOnly)
  • 获取(或设置)值(.GetValue(), .SetValue())
  • 要求转换器格式化/解析值 (.Converter, .ConvertFromString(), .ConvertToString()) < strong>这是一个关键位,意味着您不必担心数据类型是什么
  • 向它询问标题(.DisplayName,或 .Name 如果它为空/null)
  • 询问它是否支持特定于属性的通知(.SupportsChangeEvents)
  • 要求它添加/删除更改处理程序(.AddValueChanged().RemoveValueChanged())
  • 您可能还想查看对象是否支持集中通知(查找INotifyPropertyChanged)

如果您可能绑定(bind)到列表 而不是单个对象: - 列表可能在 IListSource 之后被抽象化 - 该列表可能具有自定义属性,因此请检查 ITypedList - 否则,识别项目的 Type 并使用 TypeDescriptor.GetProperties(type) - 你需要考虑一个“货币管理器”(即绑定(bind)到同一个列表的所有东西是否应该一直指向列表中的同一条记录)

还有 ICustomTypeDescriptorTypeDescriptionProvider 之类的东西需要考虑,但大多数时候 TypeDescriptor 会自动为您处理。

如您所见 - 有很多事情需要考虑!很多工作……您不需要做的一件事就是反射(reflection);这是在 PropertyDescriptor 后面抽象出来的。这样做的原因是并非所有数据都是静态类型的。考虑 DataTable - 列(映射到可绑定(bind)数据属性)在编译时不固定,因此反射不合适。同样,其他一些类型也有自定义的“属性包”实现。 PropertyDescriptor 允许您的代码以相同方式处理动态(不是 4.0 意义上的)和反射属性。它还可以很好地与“HyperDescriptor”之类的东西一起使用,这是另一个属性定制。

关于c# - 将简单绑定(bind)到“文本属性”的解决方案扩展到多个控件以处理与任何类型的绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2391828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com