【问题标题】:How to Bind a custom class with no strongly typed properties如何绑定没有强类型属性的自定义类
【发布时间】:2010-10-12 08:45:54
【问题描述】:

大家好,这是我的要求:

我需要一个简单的类,只有一个公共属性,没有公共方法(最终的类会更复杂,但我只需要测试这个)

属性是“Item”并采用“String”作为参数。它根据参数返回一个“String”。

然后我希望能够将此对象的实例添加到 ListArray,然后将其绑定到 Repeater列表视图...

...最重要的是,我希望能够通过 Eval 函数引用我的简单类中的值:

") %>**.

这是我的问题:

  1. 除非我将 Item 属性声明为 Default 属性,否则我根本无法绑定...为什么?

  2. 当我使用“Eval”时,出现“[某些属性] 不存在”行中的错误。确实没有,因为所有内容都是通过 Item 属性访问的。如果我将“Eval”替换为“Container.DataItem”,它就会起作用。

那么,有没有办法使用 Eval 代替 Container.DataItem?我宁愿不让我的类继承任何其他类,因为我想让它免受多余的属性和/或方法的影响。

有没有我需要实现的接口?

另外,我之所以要使用Eval,是为了尽可能让这个Class的使用变得简单,这样编码者就不用担心特殊情况了.我只是希望它能够工作,就像 DataTable 类一样,但实现更简单、更轻量级。

干杯

【问题讨论】:

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


    【解决方案1】:

    您的问题源于使用参数化属性(也就是使用字符串参数的属性)。参数化属性通常只有在它们是默认属性并公开某个对象的索引集合时才有意义。 (参见C# indexers)C# 只允许索引器被参数化,而 VB 对此限制更为宽松。

    假设类如下:

    Public Class TempClass
      Private strItem As New StringDictionary()
    
      Public Property Item(ByVal s As String) As String
        Get
          Return strItem(s)
        End Get
        Set(ByVal value As String)
          strItem(s) = value
        End Set
      End Property
    End Class
    

    Eval 函数需要有效公共属性的名称。当您使用参数化属性时,签名不同于您可以在 Eval 函数中指定的签名。如果您使用以下语法:

    <asp:Label ID="lbl1" runat="server" Text='<%#Eval("Item(""a"")")%>' />
    

    ...它没有解决。

    您的解决方案有三个:

    一个。评估为什么需要将此属性参数化。如果它传递了一个可以从集合中查找的键,这对我来说是有意义的。

    b.不要使用 Eval 关键字,而是使用扩展语法并手动执行转换:

    <asp:Label ID="lbl1" runat="server" Text='<%#CType(Container.DataItem, MyCustomClass).Item("a") %>' />
    

    c。还要考虑如何将不同的密钥传递给中继器中的每条记录。如果接受整数索引,这可能是理想的,以便我们可以将其链接到转发器的行号。将上面的类修改如下:

    Public Class TempClass
      Private strItems(3) As String
    
      Public Sub New()
        strItems(0) = "x"
        strItems(1) = "y"
        strItems(2) = "z"
      End Sub
    
      Public Property Items(ByVal i As Integer) As String
    Get
          Return strItems(i)
    End Get
    Set(ByVal value As String)
          strItems(i) = value
    End Set
      End Property
    End Class
    

    然后我们可以在数组中渲染适当的项目,如下所示:

    <asp:Label ID="lbl1" runat="server" Text='<%#CType(Container.DataItem, TempClass).Items(Container.ItemIndex) %>' />
    

    根据要求编辑:


    d) 修改类以使用默认属性:

    Default Public Property Item(ByVal s As String) As String
      Get
        Return strItem(s)
      End Get
      Set(ByVal value As String)
        strItem(s) = value
      End Set
    End Property
    

    数据绑定现在变成:

    <span><%#Eval("(a)")%></span>
    <asp:Label ID="lbl2" runat="server" Text='<%#Eval("(b)")%>' />
    

    【讨论】:

    • 感谢 Cerebrus。所以我想底线是,我不能使用更简单的 Eval。你是对的,我需要一个参数化的属性。我想我想要的是一种类似于 DataTable 中的 DataRow 的行为,您可以在其中使用 Eval。但是 DataRow 需要大量开销...?
    • Cerebrus,作为后续问题:当我尝试将相同的简单类列表绑定到具有自动生成列的网格视图时,我得到“网格没有任何属性或属性”。有什么解决方法...我必须屈服于 DataTable 吗?欢呼
    • @Andy:Datarow 行为是可能的,因为它将传递的 ColumnName 中的值公开为默认属性。如果您修改上面的类来模仿它,那么您不需要使用“Item”属性名。因此,您可以在这种情况下使用 Eval("a")。
    • @Cerebrus:非常感谢。我有点理解,但不完全确定如何实施。您能否发布上述课程的示例,但使用 mod ?我会在这里尝试一下,看看效果如何。再次感谢
    【解决方案2】:

    关于这个 Andy 的教程太多了!你寻找/搜索过它们吗?

    您的意思是您只想创建一个对象(类)并将其用作数据控件的数据源,如果您不想在代码中做任何事情,您可以随时使用 ObjectDataSource。

    【讨论】:

    • 嘿,balexande,感谢您的帮助。是的,我进行了搜索,但没有找到任何涉及我问题特殊性的内容。另外,我想知道您是否误解了我的问题,因为 ObjectdataSource 的好处是无关紧要的。
    • 当然我做了...我的意思是关于数据对象的教程,比如构建一个可以绑定到任何东西的类,我特别喜欢那些包含 3.5SP1 技巧的教程,只需下载这个代码并自行查找,查看 SalesPerson/DAO 对象:is.gd/mPXv
    【解决方案3】:

    除非您使用对象数据源,否则您不能在类上使用 Eval。

    "Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control."
    

    【讨论】:

    • 这是一个错误的说法。 Eval() 与 ObjectDataSource 控件没有任何关系。您始终可以将控件绑定到 IEnumerable 类。
    • 是的,澄清一下,我的班级正在进入一个列表,然后被分配到中继器的数据源。
    • 哦,上面的错误信息来自 ASP.NET。这就是我解释信息的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    相关资源
    最近更新 更多