尝试在对象列表和数据列表控件之间使用数据绑定。我想做的是
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="DataList1" runat="server" DataKeyField="ClassID" ViewStateMode="Enabled">
<ItemTemplate>
<asp:TextBox ID="txtValue1" runat="server" Text='<%# Bind("Value1") %>'></asp:TextBox>
<asp:TextBox ID="txtValue2" runat="server" Text='<%# Bind("Value2") %>'></asp:TextBox>
<asp:TextBox ID="txtvalue3" runat="server" Text='<%# Bind("Value3") %>'></asp:TextBox>
</ItemTemplate>
</asp:DataList>
<asp:Button ID="btnDoPostBack" runat="server" Text="Do Post Back" />
</div>
</form>
</body>
Option Explicit On
Option Strict On
Imports System.Diagnostics
Partial Class _Default
Inherits System.Web.UI.Page
Dim Class1List As List(Of Class1)
Protected Sub Page_PreLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreLoad
Dim txtValue1 As TextBox
Dim txtValue2 As TextBox
Dim txtValue3 As TextBox
Dim ItemIndex As Integer = 0
If Page.IsPostBack Then
Class1List = CType(Session("Class1List"), List(Of Global.Class1))
'Class1List = CType(DataList1.DataSource, List(Of Global.Class1))
For Each myDataListItem As DataListItem In DataList1.Items
txtValue1 = CType(myDataListItem.FindControl("txtValue1"), TextBox)
Long.TryParse(txtValue1.Text, Class1List(ItemIndex).Value1)
txtValue2 = CType(myDataListItem.FindControl("txtValue2"), TextBox)
Integer.TryParse(txtValue2.Text, Class1List(ItemIndex).Value2)
txtValue3 = CType(myDataListItem.FindControl("txtValue3"), TextBox)
Class1List(ItemIndex).Value3 = txtValue3.Text
ItemIndex += 1
Next
End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim myClass1 As Class1
If Not Page.IsPostBack Then
Class1List = New List(Of Class1)
myClass1 = New Class1
Class1List.Add(myClass1)
BindData()
Else
'Class1List = CType(DataList1.DataSource, List(Of Global.Class1))
Debug.WriteLine("Page_Load, Value1 = " & Class1List(0).Value1.ToString())
Debug.WriteLine("Page_Load, Value2 = " & Class1List(0).Value2.ToString())
Debug.WriteLine("Page_Load, Value3 = " & Class1List(0).Value3)
End If
End Sub
Protected Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Unload
Session("Class1List") = Class1List
End Sub
Sub BindData()
DataList1.DataSource = Class1List
DataList1.DataBind()
End Sub
Protected Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemDataBound
Dim myClass1 As Class1
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
myClass1 = CType(e.Item.DataItem, Class1)
Debug.WriteLine("DataList1_ItemDataBound, Value1 = " & myClass1.Value1.ToString())
Debug.WriteLine("DataList1_ItemDataBound, Value2 = " & myClass1.Value2.ToString())
Debug.WriteLine("DataList1_ItemDataBound, Value3 = " & myClass1.Value3)
End If
End Sub
Protected Sub btnDoPostBack_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnDoPostBack.Click
Dim myRandom As New Random
Class1List(0).Value1 = myRandom.Next(100)
Class1List(0).Value2 = myRandom.Next(100)
Class1List(0).Value3 = myRandom.Next(100).ToString()
Debug.WriteLine("btnDoPostBack_Click, Value1 = " & Class1List(0).Value1.ToString())
Debug.WriteLine("btnDoPostBack_Click, Value2 = " & Class1List(0).Value2.ToString())
Debug.WriteLine("btnDoPostBack_Click, Value3 = " & Class1List(0).Value3)
BindData()
End Sub
End Class
Class Class1很简单:
Option Explicit On
Option Strict On
Imports Microsoft.VisualBasic
Public Class Class1
Private _ClassID As Long
Private _Value1 As Long
Private _Value2 As Integer
Private _value3 As String = String.Empty
Public Property ClassID As Long
Get
Return _ClassID
End Get
Set(ByVal value As Long)
_ClassID = value
End Set
End Property
Public Property Value1 As Long
Get
Return _Value1
End Get
Set(ByVal value As Long)
_Value1 = value
End Set
End Property
Public Property Value2 As Integer
Get
Return _Value2
End Get
Set(ByVal value As Integer)
_Value2 = value
End Set
End Property
Public Property Value3 As String
Get
Return _value3
End Get
Set(ByVal value As String)
_value3 = value
End Set
End Property
End Class
更新:我得到了上面的代码来做我想做的事情 - 我在想有更好的方法吗?
答案 0 :(得分:3)
您没有显示数据绑定“加载”阶段(将数据从列表绑定到控件的代码) - 所以我假设你的部分不满意的是“保存”阶段(Page_PreLoad
中的代码将修改后的值从控件绑定到到列表),即#4 in你的清单:
将ui中的更改绑定到对象列表
听起来你想要“双向数据绑定”:你希望.NET能够像模拟中读取一样轻松地更新你的模型。这是common complaint。一个解决方案是subclass WebControl,但那是一团糟。
您已使用<%# Bind("...") %>
语法,因此您有正确的想法。该方法应该与<asp:SqlDataSource>
,开箱即用,但您想要更新自定义类,因此您需要使用<asp:ObjectDataSource>
。使用this article中的方法,但使用ObjectDataSource而不是SqlDataSource。
但首先,您必须通过使用[System.ComponentModel.DataObject]标记并指定适当的更新方法,使您的模型(即Class1
)与ObjectDataSource兼容:
[System.ComponentModel.DataObjectMethodAttribute(
System.ComponentModel.DataObjectMethodType.Update, true)]
public bool UpdateProduct(string productName, ...) {
...
}
这将允许您在webform上使用ObjectDataSource,最后获得漂亮的双向数据绑定。阅读链接以获取完整的详细信息。
Visual Studio提供了各种笨重的自动化方式,例如TableAdapters和臭名昭着的Strongly-Typed DataSet (STD),但这些方法无法帮助像您这样拥有自己的对象模型的人。无论如何我不推荐STD。
我在想有更好的方法吗?
我不认为你目前的方法很糟糕。如果您担心网络表格中存在大量逻辑,那么使用MVC方法可以获得更多,而不是担心绑定糖......