DetailsView和FormView
这两个控件都是为了只显示一行数据用的。DetailsView是个HTML Table 的底子,FormView就是可以随意发挥。既然一次数据绑定是一个DataSet,但只显示一行,就有了分页的概念。上一个记录,下一个记录,开始,结束等等。
DetailsView基本上对应GridView,不过一个Field(BoundField, TemplateField)是一行,GridView中一个Field是一列。FormView对应的是ListView,ListView也是不受 HTML Table的限制,可以随意发挥那种。
1. DetailsView介绍
下面是个DetailsView的例子,微软就喜欢兜售那些数据不分层的东西,DetailsView表现尤其明显。如果用SqlDataSource来 Bind DetailsView,就很简单。更新起来很容易,直接在SqlDataSource中写好Storeprocedure的名字即可。如果自己找个 DataSet就很费劲。
<asp: DetailsView GridLines="Both" ID=" DetailsView1" AutoGenerateRows="false"
runat="server" Height="50px" Width="840px"
onitemdeleting=" DetailsView1_ItemDeleting"
onmodechanging=" DetailsView1_ModeChanging" AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True" AutoGenerateInsertButton="True"
onitemupdating=" DetailsView1_ItemUpdating"
onitemupdated=" DetailsView1_ItemUpdated">
<Fields >
<asp:BoundField HeaderText="User LastName" DataField="LastName" />
<asp:BoundField HeaderText = "old age" DataField="Age" DataFormatString="{0:C}" />
<asp:TemplateField>
<HeaderTemplate>
<asp:Label Text="First Name:" runat = "server"></asp:Label>
</HeaderTemplate>
<ItemTemplate >
<asp:Label ID="lblFirstName" Text='<%#Bind("FirstName" ) %>' runat="server"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="tbxFirstName" Text='<%#Bind("FirstName" ) %>' runat="server"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Fields >
</asp: DetailsView>
在这个DetailsView中,分成两列。前面那一列是HeaderTemplate,后面一列是ItemTemplate。可以有三个按钮,通过 AutoGenerateButton来选择,显示还是不显示。如果点击了Edit 按钮,在DetailsView事件响应中,用DetailsView.ChangeMode来改变状态。只有改变成编辑状态,下一步Update才能有 效。否则就会报错,说不能改云云。
在Update的事件响应中有个EventArg变量,变量有两个属性,NewValues,OldValues,如果使用SqlDataSource, 在DataSource中设定一下UpdateParameter即可.如果是自己定义的DataSet就很费劲,才能得到Update之后的数据。
这个Code是示范如何读取Update后的数据
protected void DetailsView1_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
var dr = e.NewValues;
for (int j = 0; j < DetailsView1.Rows.Count-1; j++)
{
DetailsView1.Fields[j].ExtractValuesFromCell(e.NewValues, (DataControlFieldCell)DetailsView1.Rows[j].Cells[1], DataControlRowState.Edit, true);
}
string[] keys = new string[e.NewValues.Count];
e.NewValues.Keys.CopyTo(keys, 0);
e.Cancel = true;
}
DetailsView和FormView都有一遍折腾,就是一开始在ReadOnly模式下,点一下Edit,才能进入编辑模式。在编辑模式中点 Update,才能触发ItemUpdating事件,然后才能进入保存。在Readonly模式下,如果人为做一个Update Button,后果就是出Exception。每一次都要在Server侧操作,这样对用户来讲,要忍受多次Postback,性能不好。
2. FormView 介绍
FormView就是完全由用户定义,所以Template也多,有ItemTemplate, EditItemTemplate, InsertItemTemplate, FooterTemplate, HeaderTemplate, EmptyDataTemplate, PagerTemplate.
命令如下,Edit, Cancel, Update, New, Insert, Delete. 就是建一个LinkButton,Button什么的,把CommandName设定成上面几个,然后就可以自动转换模式,触发事件。转换模式其实就是用 ChangeMode()方法,触发事件倒是没啥稀罕,毕竟OnClick也能弄出点动静出来。
这是个例子。
<asp:FormView ID="FormView1" runat="server"
onitemupdated="FormView1_ItemUpdated" onitemupdating="FormView1_ItemUpdating">
<EditItemTemplate>
<asp:Label Text="FirstName" runat="server"></asp:Label>
<asp:TextBox ID="tbxFirstName" Text='<%# Bind("FirstName" )%>' runat="server"></asp:TextBox>
<br />
<asp:Label ID="lblLastName" Text="LastName" runat="server"></asp:Label>
<asp:TextBox ID="tbxLastName" Text='<%# Bind("LastName" )%>' runat="server"></asp:TextBox>
<br />
<asp:Label ID="lblAge" Text="Age" runat="server"></asp:Label>
<asp:TextBox ID="tbxAge" Text='<%# Bind("Age" ) %>' runat="server"></asp:TextBox>
<br />
<asp:LinkButton ID="lnkUpdate" runat="server" CommandName="Update" Text="Update"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" Text="FirstName" runat="server"></asp:Label>
<asp:TextBox ID="tbxFirstName" Text='<%# Bind("FirstName" )%>' runat="server"></asp:TextBox>
<br />
<asp:Label ID="lblLastName" Text="LastName" runat="server"></asp:Label>
<asp:TextBox ID="tbxLastName" Text='<%# Bind("LastName" )%>' runat="server"></asp:TextBox>
<br />
<asp:Label ID="lblAge" Text="Age" runat="server"></asp:Label>
<asp:TextBox ID="tbxAge" Text='<%# Bind("Age" ) %>' runat="server"></asp:TextBox>
<br />
<asp:LinkButton ID="lnkUpdate" runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:FormView>
和DetailsView一样,如果不是从DataSource来的数据,取得数据也比较费劲。只能通过FindControl来操作。e.OldValues 和e.NewValues都不要用。
string first = ((TextBox)FormView1.FindControl("tbxFirstName" )).Text;