将控件绑定到类属性 - 这在技术上是否可行?

时间:2009-03-20 17:44:38

标签: c# .net asp.net vb.net data-binding

我还没有找到一种在网络中进行双向数据绑定的“好方法”。
我不喜欢的一件事就是在现在的asp.net双向数据绑定中,在aspx页面中进行绑定是没有编译时检查,即:

<asp:TextBox ID="TitleTextBox"
            runat="server"            Text='<%# Bind("Title_oops_spelled_wrong") %>'>

我想有这样的事情:

Class Binder
Public Sub BindControl(ctl As Control, objectProperty As ???????)
  '// Add ctl and objectProperty to a collection

End Sub

我不知道的是,如何在我的例子中接收objectProperty;我希望收到属性的引用(即:指针),所以稍后,通过这个引用,我可以读取或写入属性。

这可能以某种方式与代表完成吗?

更新:
注意,我想将控件引用添加到绑定集合中,然后此集合将用于绑定和解除绑定。

3 个答案:

答案 0 :(得分:2)

您是否有理由避免使用.NET数据绑定机制?它处理控件的值和类的属性值之间的奇偶校验,并提供丰富的设计时支持。

您可以通过两种方式与数据绑定引擎进行交互:以编程方式或通过设计器。以编程方式进行基本数据绑定是微不足道的。假设我有一个名为“FooClass”的类,其字符串属性名为“MyString”。我有一个名为myTxtBox的TextBox,它在一个名为foo的FooClass实例的表单上,我想将它绑定到MyString属性:

myTxtBox.DataBindings.Add("Text", foo, "MyString");

执行此操作将导致TextBox的更新被分配给属性,并且从其他地方对属性的更改将反映在TextBox中。

对于更复杂的数据绑定方案,您可能希望在项目中创建一个Object Data Source并在表单上放置一个BindingSource。如果您需要有关创建数据源的特定步骤的帮助,我可以提供帮助,但通常您将在项目中创建源并选择要绑定的类。然后,您可以在表单上放置BindingSource,将其指向对象项目数据源,然后使用Visual Studio设计器将控件的属性绑定到对象的属性。然后,将代码中的DataSource属性设置为要绑定到的类或集合的实例。

作为附注,据我所知,没有“属性委托”,因为属性实际上是函数对(get_和set _)。

更新:

在我阅读您的评论时,我想指出.NET数据绑定,即使在控件级别,也不会自动使用反射。数据绑定是围绕绑定控件和数据源的类型描述符和属性描述符构建的。确实,如果这些方面中的一方或双方没有实现特定的属性和类型描述,那么将使用反射,但是任何一方都可以自由地提供它自己的描述配置文件,它不会使用反射。

答案 1 :(得分:0)

Bind不是一种方法,并且场景背后没有一些对象存在绑定关系。它只是页面解析器用于生成代码的“神奇”词。从本质上讲,它转换为Eval并控制构建代码。另一方面,Eval将使用反射来访问绑定项的属性。

如果我正确理解你想要的东西,那么只读属性绑定已经有效了。假设你班上有一个属性Title:

<asp:TextBox ID="TitleTextBox" runat="server" Text='<%# Title %>' />

对于双向绑定,您必须创建自己的模板或反映现有模板并传递ExtractTemplateValuesMethod方法并将DataBinding事件分配给控件。这是.NET使用Eval的地方,您将使用属性赋值替换它。

在我看来,这就是DataBinding事件的用途。

但是,如果你质疑更多关于一个人是否可以引用一个财产,那么我恐怕不会。每个人都没有财产。您必须使用方法(获取和设置)以及元数据中的条目。您可以存储对象和属性名称的引用,但是您必须使用反射。

您可以使用委托,但这将使您回到与.NET生成的代码相同的代码,无论如何定义ExtractTemplateValuesMethod并执行DataBinding。

答案 2 :(得分:0)

一种解决方案是传递objectProperty ByRef。

如果要进行编译时类型检查,则需要为计划使用的任何类型重载BindControl。例如:

Public Sub BindControl(ctl As ITextControl, ByRef objectProperty As String)
    objectProperty = ITextControl.Text
End Sub

Public Sub BindControl(ctl As ITextControl, ByRef objectProperty As Integer)
    Integer.TryParse(TextControl.Text, objectProperty)
End Sub
..