- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题是:如何超越编写数据绑定(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)(对于简单的属性,手动完成)包括:
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)到同一个列表的所有东西是否应该一直指向列表中的同一条记录)
还有 ICustomTypeDescriptor
和 TypeDescriptionProvider
之类的东西需要考虑,但大多数时候 TypeDescriptor
会自动为您处理。
如您所见 - 有很多事情需要考虑!很多工作……您不需要做的一件事就是反射(reflection);这是在 PropertyDescriptor
后面抽象出来的。这样做的原因是并非所有数据都是静态类型的。考虑 DataTable
- 列(映射到可绑定(bind)数据属性)在编译时不固定,因此反射不合适。同样,其他一些类型也有自定义的“属性包”实现。 PropertyDescriptor
允许您的代码以相同方式处理动态(不是 4.0 意义上的)和反射属性。它还可以很好地与“HyperDescriptor”之类的东西一起使用,这是另一个属性定制。
关于c# - 将简单绑定(bind)到“文本属性”的解决方案扩展到多个控件以处理与任何类型的绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2391828/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!