5.9 完善GridView编辑功能
学习目标
进一步熟悉GridView使用。
5.9.1 转换模板列
编辑功能主要是完善编辑模板显示的表单效果,而要自定义编辑模板表单的显示效果,也必须把这些字段列先转换成模板列,转换方法和“维护”列转换为模板列的方法一样,这里就直接给出结果了,如图5-41所示。
其中的编号字段由于是数据表test的主键(Primary Key)字段,故不能修改,也就不用转换模板列,可以看出,转换模板列后,图5-41中的列标题图标下面多了个小图标。由此可以直观看出哪些列是模板列,哪些不是模板列。
5.9.2 完善系统生成的SqlDataSource代码
(1)全部字段(列)都转换成模板列之后,再回到gv02.aspx的HTML脚本页面,接下来给出gv02.aspx页面的完整HTML脚本代码。
<body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView1" runat="server" AllowPaging= "Truen"AllowSorting="True"AutoGenerateColumns="False" DataKeyNames="id"DataSourceID="SqlDataSource1"> <Columns> <asp:TemplateField HeaderText="维护" ShowHeader= "False"> <EditItemTemplate> <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" CommandName="Update" Text="更新"></ asp:LinkButton> <asp:LinkButton ID="LinkButton2"runat ="server" CausesValidation="False"Command Name="Cancel" Text="取消"></asp:LinkButton> </EditItemTemplate> <ItemTemplate> <asp:LinkButton ID="LinkButton1" runat= "server"CausesValidation="False" Command Name="Edit" Text="编辑 "></asp:LinkButton> <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Delete" OnClientClick= "return confirm('确认删除吗?');" Text=" 删除"></asp:LinkButton> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="id" HeaderText="编号" InsertVisible="False" ReadOnly= "True"SortExpression="id" /> <asp:TemplateField HeaderText="姓名"SortExpression ="name"> <EditItemTemplate> <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("name") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Bind("name") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="性别" SortExpression ="sex"> <EditItemTemplate> <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("sex") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label2" runat="server"Text= '<%# Bind("sex") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="城市"SortExpression ="city"> <EditItemTemplate> <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("city") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label3" runat="server" Text= '<%# Bind("city") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="生日" SortExpression ="birthday"> <EditItemTemplate> <asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("birthday") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label4" runat="server" Text ='<%# Bind("birthday") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="备注"SortExpression ="note"> <EditItemTemplate> <asp:TextBox ID="TextBox5" runat="server" Text='<%# Bind("note") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label5" runat="server"Text ='<%# Bind("note") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConflictDetection="CompareAllValues" ConnectionString="<$ Connectio nStrings:mydbConnectionString %>" DeleteCommand="DELETE FROM [test] WHERE [id] = @original_id AND ( ([name] = @original_name) OR ([name] IS NULL AND @original_name IS NULL)) AND (([sex] = @original_sex) OR ([sex] IS NULL AND @original_sex IS NULL)) AND (([city] = @original_city) OR ([city] IS NULL AND @original_city IS NULL)) AND (([birthday] = @original_birthday) OR ([birthday] IS NULL AND @ original_birthday IS NULL)) AND (([note] = @original_note) OR ([note] IS NULL AND @original_note IS NULL))" InsertCommand="INSERT INTO [test] ([name], [sex], [city], [birthday], [note]) VALUES (@ name, @sex, @city, @birthday, @note)" OldValuesParameterFormatStrin g="original_{0}" SelectCommand="SELECT [id], [name], [sex], [city], [birthday], [note] FROM [test] ORDER BY [id]" UpdateCommand="UPDATE [test] SET [name] = @name, [sex] = @sex, [city] = @city, [birthday] = @birthday, [note] = @note WHERE [id] = @original_id AND (([name] = @original_name) OR ([name] IS NULL AND @original_name IS NULL)) AND (([sex] = @original_sex) OR ([sex] IS NULL AND @original_sex IS NULL)) AND (([city] = @original_city) OR ([city] IS NULL AND @ original_city IS NULL)) AND (([birthday] = @original_birthday) OR ([birthday] IS NULL AND @original_birthday IS NULL)) AND (([note] = @original_note) OR ([note] IS NULL AND @original_note IS NULL))"> <DeleteParameters> <asp:Parameter Name="original_id" Type="Int32" /> <asp:Parameter Name="original_name" Type="String" /> <asp:Parameter Name="original_sex" Type="String" /> <asp:Parameter Name="original_city" Type="String" /> <asp:Parameter Name="original_birthday" Type="Date Time" /> <asp:Parameter Name="original_note" Type="String" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="name" Type="String" /> <asp:Parameter Name="sex" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="birthday" Type="DateTime" /> <asp:Parameter Name="note" Type="String" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="name" Type="String" /> <asp:Parameter Name="sex" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="birthday" Type="DateTime" /> <asp:Parameter Name="note" Type="String" /> <asp:Parameter Name="original_id" Type="Int32" /> <asp:Parameter Name="original_name" Type="String" /> <asp:Parameter Name="original_sex" Type="String" /> <asp:Parameter Name="original_city" Type="String" /> <asp:Parameter Name="original_birthday" Type="Date Time" /> <asp:Parameter Name="original_note" Type="String" /> </UpdateParameters> </asp:SqlDataSource> </div> </form> </body>
(2)首先关注加粗部分代码,也就是SqlDataSource部分代码,这里是系统生成的代码,最后能修改一下,例如删除指令:
DeleteCommand="DELETE FROM [test] WHERE [id] = @original_id AND (([name] = @original_name) OR ([name] IS NULL AND @original_ name IS NULL)) AND (([sex] = @original_sex) OR ([sex] IS NULL AND @original_sex IS NULL)) AND (([city] = @original_city) OR ([city] IS NULL AND @original_city IS NULL)) AND (([birthday] = @original_ birthday) OR ([birthday] IS NULL AND @original_birthday IS NULL)) AND (([note] = @original_note) OR ([note] IS NULL AND @original_ note IS NULL))"
只需要和主键id关联即可,不用和其他字段关联,故上述删除指令代码可以修改为:
DeleteCommand="DELETE FROM [test] WHERE [id] = @original_id"
再比如修改指令:
UpdateCommand="UPDATE [test] SET [name] = @name, [sex] = @sex, [city] = @city, [birthday] = @birthday, [note] = @note WHERE [id] = @original_id AND (([name] = @original_name) OR ([name] IS NULL AND @original_name IS NULL)) AND (([sex] = @original_sex) OR ([sex] IS NULL AND @original_sex IS NULL)) AND (([city] = @original_city) OR ([city] IS NULL AND @original_city IS NULL)) AND (([birthday] = @ original_birthday) OR ([birthday] IS NULL AND @original_birthday IS NULL)) AND (([note] = @original_note) OR ([note] IS NULL AND @ original_note IS NULL))"
修改指令要修改的项目可能是多个字段,但是关联条件通常也是和主键id关联即可,不用和其他字段关联,故上述修改指令代码可以修改为:
UpdateCommand="UPDATE [test] SET [name] = @name, [sex] = @sex, [city] = @ city, [birthday] = @birthday, [note] = @note WHERE [id] = @original_id "
由于很少使用GirdView完成数据添加功能,故可以把其中的添加指令INSERT直接删除。
后面的代码给出的是删除指令、添加指令、修改指令的参数设置部分代码,由于指令的变化,参数设置部分当然要跟着变了。已经没有添加指令了,故添加指令参数部分就可以完全删除了,而删除部分只和主键id有关,故其他参数可以删除了。而更新操作只和original_id这个原始值有关,故其他original参数就可以删除了。
接下来给出修改后的SqlDataSource部分代码,这样看来代码页不是很复杂了。
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConflictDetection="CompareAllValues" ConnectionString="<$ ConnectionStrings:mydbConnectionString %>" DeleteCommand="DELETE FROM [test] WHERE [id] = @original_id" OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT [id], [name], [sex], [city], [birthday], [note] FROM [test] ORDER BY [id]" UpdateCommand="UPDATE [test] SET [name] = @name, [sex] = @sex, [city] = @city, [birthday] = @birthday, [note] = @note WHERE [id] = @original_id"> <DeleteParameters> <asp:Parameter Name="original_id" Type="Int32" /> </DeleteParameters> <UpdateParameters> <asp:Parameter Name="name" Type="String" /> <asp:Parameter Name="sex" Type="String" /> <asp:Parameter Name="city" Type="String" /> <asp:Parameter Name="birthday" Type="DateTime" /> <asp:Parameter Name="note" Type="String" /> <asp:Parameter Name="original_id" Type="Int32" /> </UpdateParameters> </asp:SqlDataSource>
(3)到此为止,系统生成的SqlDataSource代码完善完毕。
5.9.3 修改GridView行高、列宽
为了完善GridView编辑功能的显示效果和运行效果,需要调整GridView的行高和列宽设置,通常最好不要直接拖曳GridView控件改变控件的宽度、高度,这样一来就不好控制了。
1.设置字体、字体大小
在页面gv02.aspx设计窗口,右击页面上的GridView控件,在弹出的快捷菜单中选择“属性”命令,然后打开GridView控件属性编辑窗口,设置整个GridView控件中的字体、字体大小,如图5-42所示。
2.调整行高
这里的行高,通常分为页眉行高、数据项行高、交错项行高、页脚行高、分页项行高。
对应GridView属性窗口中的如下属性。
(1)页眉行高:HeaderStyle中的Height设置为30px。
(2)数据项行高:RowStyle中的Height的Height设置为30px。
(3)交错项行高:AlternatingRowStyle中的Height的Height设置为30px。
(4)页脚行高:FooterStyle中的Height的Height设置为30px。
(5)分页项行高:PageStyle中的Heigt的Height设置为30px。
3.调整列宽
调整列宽,首先要进入编辑列窗口,然后选择某个列,如编号,如图5-43所示。
在图5-43中,在“样式”的“Item-Style”中,设置Width为100px,其他列的设置方法依此类推,依次设置如下。
“维护”:Width设置为100px。
“编号”:Width设置为60px。
“姓名”:Width设置为120px。
“性别”:Width设置为80px。
“城市”:Width设置为120px。
“生日”:Width设置为150px。
“备注”:Width设置为150px。
全部设置完成后,页面gv02.aspx运行显示效果如图5-44所示。
5.9.4 处理姓名文本框编辑
页面gv02.aspx运行后,单击某行的“编辑”按钮,显示出来的编辑项姓名文本框显然太长了,影响了页面的显示效果,这就需要编辑姓名的编辑项模板,因此,本书上文才详细说明了设置模板列、行高、列宽的方法。
(1)在gv02.aspx页面的设计窗口,单击页面GridView控件,然后单击右上角的小图标,进入“GridView任务”面板,如图5-45所示。
(2)在图5-45中,选择“GridView任务”面板最下面的“编辑模板”项目,显示窗口如图5-46所示。
(3)在图5-46中,选择“Column[2] - 姓名”,显示如图5-47所示,其中Item-Template就是数据项(奇数项)模板的定义,AlternatingItemTemplate就是交错项(偶数项)模板的定义,EditItemTemplate就是编辑项模板的定义,HeaderTemplate就是页眉模板的定义,FooterTemplate就是页脚模板的定义,根据以上描述可以看出,这里需要处理的就是EditItemTemplate。
可以看出,EditItemTemplate这里的文本框就是用户在gv02.aspx页面上单击“编辑”按钮后显示的编辑项模板样子,选择EditItemTemplate中的文本框,然后在属性窗口中设置该文本框的显示样子。
(4)设置图5-47中的EditItemTemplate中的文本框的样式属性:
Width为80px,Height为20px,BorderColor为#CC0000,BorderStyle为Solid,BorderWidth为2px。设置完成后,显示如图5-48所示。
(5)接下来就是给姓名的编辑项模板文本框增加数据验证控件,验证EditItem-Template中的姓名文本框不能为空,用户必须填写。在图5-48中,从工具箱的验证控件中拖动一个必填验证控件(RequiredFieldValidator)到页面上,然后设置该验证控件的属性:ControlToValidate为Text-Box1、ErrorMessage为*。
(6)在gv02.aspx页面设计窗口中右击,在弹出的快捷菜单中选择“在浏览器查看”命令,即可看到运行结果,然后单击某行的“编辑”按钮,出现的错误窗口如图5-49所示。
(7)出现上述错误,是因为Web Form使用UnobtrusiveValidationMode来验证的,所以可以设定不要使用UnobtrusiveValidationMode,在gv02.aspx的程序页面中的Page_Load事件中增加如下代码即可。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class gv02 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) } UnobtrusiveValidationMode = UnobtrusiveValidationMode.None; } }
(8)再次运行gv02.aspx页面,单击某行的“编辑”按钮,显示如图5-50所示。
(9)在图5-50中,如果清空姓名“ 王晓慧”,单击“更新”按钮,就不能提交了,后面就有个“*”提示不能更新,正确输入修改后的姓名,就可以更新了。
5.9.5 处理性别单选按钮编辑
(1)处理性别编辑模板,需要替换RadioButtonList控件,当然同样进入“性别”字段的编辑模板EditItemTemplate,如图5-51所示。
(2)在图5-51中,删除EditItemTemplate中的文本框,然后从工具箱中拖动一个RadioButtonList控件到EditItemTemplate中,如图5-52所示。
(3)在图5-52中,选择“RadioButtonList任务”面板中的“编辑项”项目,弹出如图5-53所示对话框。
(4)在图5-53中,添加两个成员,其Text/Value依次为:男/男、女/女,然后单击“确定”按钮。gv02.aspx显示窗口如图5-54所示。
(5)在图5-54中,选择“RadioButtonList任务”面板中的“编辑DataBindings …”项目,弹出如图5-55所示对话框。
(6)在图5-55中,左侧的“可绑定属性”选择“SelectedValue",右侧选择“自定义绑定”并在“代码表达式”中输入绑定函数表达式“Bind("sex")",然后单击“确定”按钮。运行gv02.aspx页面,然后单击某行的“编辑”按钮,显示如图5-56所示。
(7)在图5-56中,很明显就可以通过选择的方式来修改性别了,不过,性别只有两个选择,横向显示好像更好些,修改RadioButtonList控件中的“RepeatDirection”属性为“Horizontal”(水平方式)即可(默认该属性取值为Vertical垂直方式),修改后的页面运行显示效果如图5-57所示。
5.9.6 处理城市下拉列表编辑
(1)城市字段的Edit-ItemTemplate是要把文本框替换成下拉列表Drop-DownList控件,同样首先进入“城市”字段的编辑模板窗口,如图5-58所示。
(2)在图5-58中,删除EditItemTemplate中的文本框,从工具箱中拖动一个DropDownList控件到页面上,如图5-59所示。
(3)在mydb数据库中创建一个city_table表,完整脚本代码如下(也可以参见ch05/city_table.sql)。
use mydb go create table city_table ( cityid int identity primary key, cityname varchar(50) ) go insert into city_table(cityname) select distinct city from test; go select * from city_table; go
(4)在图5-59中,选择“DropDownList任务”面板中的“选择数据源”项目,弹出如图5-60所示对话框。
(5)在图5-60中,选择“选择数据源”下拉列表中的“新建数据源”,显示窗口又到了“选择数据源类型”,依然选择“数据库”项目,然后单击“下一步”按钮,显示如图5-61所示。
(6)在图5-61中,依然选择之前保存的mydb ConnectionString,然后单击“下一步”按钮,显示如图5-62所示。
(7)在图5-62中,单击“下一步”按钮进入“测试查询”对话框,在“测试查询”对话框中直接单击“完成”按钮,显示如图5-63所示。
(8)在图5-63中,在DropDownList的显示的数据字段和值字段都选择cityname(这里的练习比较特殊,都选择cityname,通常的操作是:显示的数据字段取cityname,而值字段选择cityid),然后单击“确定”按钮,显示如图5-64所示。
(9)在图5-64中,选择“DropDownList任务”面板中的“编辑DataBindings…”项目,弹出如图5-65所示对话框。
(10)在图5-65中,按照图中的选择,在代码表达式中输入“Bind("city")”,然后单击“确定”按钮,再次运行gv02.aspx页面,然后单击某行的“编辑”按钮,显示效果如图5-66所示,可以看出已经可以通过下拉列表来修改“城市”字段了。