显式将数据绑定到 ListView Web 控件





4.00/5 (9投票s)
无需 SqlDataSource 和 Eval / Bind 方法绑定数据。
引言
众所周知,使用 Eval 和 Bind 方法可能成本很高。使用此方法和 数据绑定表达式 的控件包括 GridView
、DetailsView
、FormView
、Repeater
和 ListView
。这些实际上是 数据绑定控件,可以绑定到 数据源控件,例如 ObjectDataSource
或 SqlDataSource
。
有方法可以降低 Eval
方法的使用成本。这里有一个如何操作的示例。如果您将这些控件(数据绑定 Web 控件)用于企业 Web 应用程序,每分钟有数千次点击,那么 Eval
方法并不是最佳解决方案。当然,一切都在 HTML 中硬编码。
在本例中,我们将不使用 Eval
或 Bind
方法,也不会使用数据源控件。我们将从服务器端完成所有操作。为了使此示例正常工作,您需要下载 .NET Framework 3.5 Service Pack 1 Beta。
为什么选择 ListView
?此控件有一个非常重要的事件,我们将大量操作它 - ItemDataBound
。此外,它还有模板,例如 ItemTemplate
和 EditItemTemplate
。我们的示例将从 DataSet
绑定数据,编辑此数据并更新它。
使用代码
我们将在 ItemTemplate
中包含 Label
控件,并在 EditItemTemplate
中包含 TextBox
控件。在“编辑模式”下,每个 Label
都将与一个 TextBox
切换。
protected void Page_Load(object sender, EventArgs e)
{
if (ProductsListView.EditItem == null)
{
ProductsListView.DataSource = LoadDataSet();
ProductsListView.DataBind();
}
}
如您所见,我们正在检查这是“查看模式”还是“编辑模式”,以便将正确的数据绑定到 ListView
控件。当进入其他事件处理程序时,这会更清楚。在调用 DataBind
方法后,会触发 ItemDataBound
事件。
protected void ProductsListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
DataRowView drv = (DataRowView)dataItem.DataItem;
if (ProductsListView.EditItem == null)
{
Label companyName = (Label)e.Item.FindControl("CompanyName");
companyName.Text = drv["CompanyName"].ToString();
Label city = (Label)e.Item.FindControl("City");
city.Text = drv["City"].ToString();
Label customerID = (Label)e.Item.FindControl("CustomerID");
customerID.Text = drv["CustomerID"].ToString();
}
...
在这里,我们再次检查正在呈现哪个模板,因为如果我们处于“查看模式”,并且我们正在寻找 TextBox
控件,我们将收到一个错误。
现在,来自 DataSet
的所有数据都绑定到 ItemTemplate
中的 Label 控件,并且页面已呈现。
“编辑”按钮的 CommandName
属性设置为“Edit”。这将触发一个新事件 - ItemEditing
。
protected void ProductsListView_ItemEditing(object sender, ListViewEditEventArgs e)
{
ProductsListView.EditIndex = e.NewEditIndex;
ProductsListView.DataBind();
}
现在,我们将 EditIndex
属性设置为正在编辑的项目的索引。同样,调用 DataBind
方法,该方法会触发 ItemDataBound
事件。
...
else if (ProductsListView.EditItem != null)
{
if (dataItem.DisplayIndex == ProductsListView.EditIndex)
{
TextBox nameTextBox = (TextBox)e.Item.FindControl("CompanyTextBox");
nameTextBox.Text = drv["CompanyName"].ToString();
TextBox cityTextBox = (TextBox)e.Item.FindControl("CityTextBox");
cityTextBox.Text = drv["City"].ToString();
TextBox customerID = (TextBox)e.Item.FindControl("CustomerIDTextBox");
customerID.Text = drv["CustomerID"].ToString();
}
}
}
此代码是 ItemDataBound
事件处理程序中“if
语句”的第二部分。在这里,我们不是在寻找 ItemTemplate
中的 Label
控件,而是在 EditItemTemplate
中寻找 TextBox
控件 (EditItem != null
)。此外,我们希望绑定正确的数据行 (DisplayedIndex == EditIndex
)。
现在,EditItemTemplate
使用绑定到 TextBox
控件的数据呈现。从这里,我们可以更改 TextBox
控件中的数据,并尝试更新更改。“更新”按钮的 CommandName
属性设置为“Update”。这将触发一个新事件,ItemUpdating
。
protected void ProductsListView_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
TextBox nameTextBox=(TextBox)ProductsListView.EditItem.FindControl("CompanyTextBox");
TextBox cityTextBox=(TextBox)ProductsListView.EditItem.FindControl("CityTextBox");
TextBox customerID=(TextBox)ProductsListView.EditItem.FindControl("CustomerIDTextBox");
Update(nameTextBox.Text, cityTextBox.Text, customerID.Text);
ProductsListView.EditIndex = -1;
ProductsListView.DataSource = LoadDataSet();
ProductsListView.DataBind();
}
现在我们处于“编辑模式”,我们正在从 EditItem
属性中寻找 TextBox
控件。
使用来自 TextBox
控件的值,我们更新数据库中的数据并关闭 EditItemTemplate
。因为所有按钮都会导致回发,所以我们在 Page_Load
的开头进行了一个检查,仅在未处于“编辑模式”时才绑定数据。现在我们处于这种模式,我们在此事件处理程序中绑定一个新的已更新的 DataSet
。
单击“取消”按钮将触发 ItemCanceling
事件。
protected void ProductsListView_ItemCanceling(object sender, ListViewCancelEventArgs e)
{
ProductsListView.EditIndex = -1;
ProductsListView.DataSource = LoadDataSet();
ProductsListView.DataBind();
}
对于 ItemUpdating
,同样适用;尽管数据未更新,但我们需要从此事件处理程序绑定数据,因为我们处于“编辑模式”。