动态将控件加载到 DataGrid 中






4.14/5 (20投票s)
2004年9月22日
3分钟阅读

158782

2450
一种在运行时向 DataGrid 加载控件,然后允许 DataSet 更新的方法。
引言
ASP.NET 的 DataGrid
是一个强大的控件,它支持嵌入文本框、按钮、下拉列表等控件…… 这种控件的强大是以复杂性为代价的。 最近,我需要生成一个屏幕,其中包含将由应用程序用户在运行时填充的数据。 数据的显示格式可能会根据用户输入而改变。 保存的数据可能来自列表的选择、True/False 条件或文本字符串。 这是一个关于数据可能如何被查看的例子。
乍一看,DataGrid
控件非常适合显示此数据。 DataGrid
将接受嵌入控件,但是,设计和嵌入最容易在 Visual Studio 中完成。 我的要求是允许用户配置数据,并动态填充屏幕。 另外一个 "可有可无" 的功能是允许通过单个按钮更新屏幕上的任何数据字段。
第 1 步 – 审查数据
为了本文的目的,我将使用 XML 文件作为持久数据存储。 这里使用的示例是一个序列化的 DataSet
,包含两个表,第一个表 – 命名为 MyDetails,包含这些重要的元素
<myDetails>
<name>Name</name>
<value>Mark</value>
<type>txtbox</type>
<populate>NameSource</populate>
</myDetails>
Name
: 正在存储的数据元素的名称;Value
: 元素的存储值;Type
: 用于呈现数据的控件;和Populate
: 用于填充DropDownList
的辅助表(当 type=ddl
时)。
此示例将支持 Textbox
('txtbox
')、CheckBox
('checkbox
') 和 DropDownList
('ddl
') 控件。 在此示例中,第二个表 – 命名为 CarMake – 填充了名为汽车制造商的 DropDownList
。 下面提供了该表的一个示例
<CarMake>
<carmake>Ford</carmake>
</CarMake>
第 2 步 – 将 DataGrid 插入到 ASPX 屏幕上
在我的例子中,我将显示两列,第一列将保存元素名称,第二列将保存实例值。 此时,我们将使网格为空。 在其他情况下,您可能希望在设计时使用与数据无关的控件填充屏幕。
<asp:datagrid BorderWidth="1" id="dg1"
style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 8px"
runat="server" AutoGenerateColumns="False" ShowHeader="False"
BorderStyle="None" GridLines="Both">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<ItemTemplate>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:datagrid>
第 3 步 – 将数据绑定到 DataGrid
绑定控件很重要,即使我们在控件中没有任何数据元素,也要为 DataSet
的每一行引发绑定事件。
dg1.DataSource = myDS
dg1.DataMember = "myDetails"
DataBind()
第 4 步 - 将控件插入到 DataGrid 中
动态插入控件的技巧是使用与屏幕上 DataGrid
控件关联的 ItemDataBound
事件。 ItemDataBound
事件将为 DataSet
中的每一行数据调用。 每次引发行事件时,都会创建相应的控件并将其插入到 DataGrid
中。 此示例使用 e.Item.DataSetIndex
将 DataGrid
行和 DataSource
行链接起来。
Private Sub dg1_ItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) _
Handles dg1.ItemDataBound
'ensure we are looking at an item being bound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = _
ListItemType.AlternatingItem Then
'always insert the dataelement name into the first column as a label.
Dim myLBL As New Label
myLBL.EnableViewState = True
myLBL.Text = dgTable(dg1).Rows(e.Item.DataSetIndex)(0)
e.Item.Cells(0).Controls.Add(myLBL)
If dgTable(dg1).Rows(e.Item.DataSetIndex)(2) = "txtbox" Then
'insert textbox and load with data
Dim myTB As New TextBox
If Not IsPostBack Then
myTB.Text = dgTable(dg1).Rows(e.Item.DataSetIndex)(1)
End If
e.Item.Cells(1).Controls.Add(myTB)
End If
If dgTable(dg1).Rows(e.Item.DataSetIndex)(2) = "checkbox" Then
'insert checkbox and load with data
Dim myCB As New CheckBox
If Not IsPostBack Then
If dgTable(dg1).Rows(e.Item.DataSetIndex)(1).tolower = "t" Then
myCB.Checked = True
Else
myCB.Checked = False
End If
End If
e.Item.Cells(1).Controls.Add(myCB)
End If
If dgTable(dg1).Rows(e.Item.DataSetIndex)(2) = "ddl" Then
'insert dropdownlist and load with data
Dim myDDL As New DropDownList
'for simplicity I will assume the ‘CarMake’ table
'always as the dropdownlist data source
For yy As Int16 = 0 To _
dg1.DataSource.Tables("CarMake").Rows.Count - 1
myDDL.Items.Add(dg1.DataSource.Tables("CarMake").Rows(yy)(0))
Next
e.Item.Cells(1).Controls.Add(myDDL)
If Not IsPostBack Then
myDDL.SelectedIndex = _
CType(dgTable(dg1).Rows(e.Item.DataSetIndex)(1), Int16)
End If
End If
End If
End Sub
'This function returns the table bound to the datagrid
Private Function dgTable(ByVal dg As DataGrid) As DataTable
Return dg1.DataSource.tables(dg1.DataMember)
End Function
第 5 步 – 允许全屏,单击按钮更新
最后,我们准备将更新后的数据传回给 DataSet
。 此示例在 prerender 事件上执行更新。 要更新,我们将逐行分析 DataGrid
并相应地更新 DataSet
。
Private Sub dg1_PreRender(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles dg1.PreRender
' this is where the dataset update actually happens!!
Dim y As Int16
'run through each line in the datagrid
For y = 0 To dgTable(dg1).Rows.Count - 1
'repopulate the dataset with content based on the embedded control
If dg1.Items(y).Cells(1).Controls(0).GetType Is GetType(DropDownList) Then
Dim myIndex As Int32 = _
CType(dg1.Items(y).Cells(1).Controls(0), DropDownList).SelectedIndex
dgTable(dg1).Rows(y)(1) = myIndex.ToString
End If
If dg1.Items(y).Cells(1).Controls(0).GetType Is GetType(TextBox) Then
Dim myStr As String = _
CType(dg1.Items(y).Cells(1).Controls(0), TextBox).Text
dgTable(dg1).Rows(y)(1) = myStr
End If
Next
dg1.DataSource.WriteXml(strFileLoc)
End Sub
结论
此示例使用了 XML 文件,并提供了仅插入三个控件的选项。 一个更完整的示例可以提供具有特定验证的控件(例如,电话号码或纯字符串)。
此示例未处理屏幕上控件引发的事件。 这将是未来提交的主题。
祝你好运,编码愉快!!