6/29 原型编码阶段:(2) GridView的数据库操作

从上面的例子可以看到,绑定数据源方面GridView同时支持DataSourceID和DataSource两个属性。
如果我们在页面内设置了DataSource控件如:SqlDataSource,AccessDataSource,ObjectDataSource,XMLDataSource或者SiteMapDataSource,那么就可以用DataSourceID来指定,并且内置了绑定,分页,排序,更新,删除等操作,一行代码都不用写。
如果我们用ADO.NET编写代码,便是绑定的DataSource,所以要明确声明GridView.DataBind(),而且所有的分页,排序,更新,删除代码都需要自己手工写。

由于列表表格的列标题直接来自于字段名,是英文的,因此首先 我们把他们改成中文名:
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ClerkID"
None.gif            DataSourceID="SqlDataSource1">
None.gif            <Columns>
None.gif                <asp:BoundField DataField="ClerkID"  HeaderText="员工编号" InsertVisible="False" ReadOnly="True"
None.gif                    SortExpression="ClerkID" />
None.gif                <asp:BoundField DataField="RealName"  HeaderText="员工姓名" SortExpression="RealName" />
None.gif                <asp:BoundField DataField="JobNum"  HeaderText="工号" SortExpression="JobNum" />
None.gif                <asp:BoundField DataField="DeptID"  HeaderText="部门编号" SortExpression="DeptID" />
None.gif            </Columns>
        </asp:GridView>
中文列名可以直接在源中修改,也可以用gridview控件的编辑列功能设置选定的字段以及每个字段的显示标题。
在这里提一下数值格式化字符串,比如我们的员工显示规则是4位 000x ,而数据库中存放的是 1,2,3那么就应该修改这一项的格式化字串,见红色代码(注意要将HtmlEncode设成"False",格式化输出才有效,但是HtmlEncode设成True可以防止字段中可能有的HTML标签和js脚本生效,避免执行恶意代码),为了让输出表格更好看,我选择了自动套用格式“雨天”,以下的蓝色代码就是系统自动修改的部分。
        <asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#999999"
            BorderStyle="None" BorderWidth="1px" CellPadding="3" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" Font-Size="10pt">
            <FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
            <RowStyle BackColor="#EEEEEE" ForeColor="Black" />
            <SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
            <HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
            <AlternatingRowStyle BackColor="Gainsboro" />

None.gif             < Columns >
None.gif                <asp:BoundField DataField="ClerkID" HeaderText="员工编号"  DataFormatString="{0:000#}"  HtmlEncode="False" 
InsertVisible="False" ReadOnly="True"  None.gif                    SortExpression="ClerkID" />
None.gif             </ Columns >
        </asp:GridView>
页面显示结果如下:
员工编号姓名工号
0001陈公客1001
0002王公客1002
0003张大客3001
0004李大客3002
我注意到了,如果对非数值型,比如字符型的字段:工号,使用格式化字符串是无效的。

下面我们对GridView添加 新增,修改和删除功能,按如下步骤设置:


确定后,系统会自动更新GridView控件的代码。这时点击智能标签,选中启用编辑,启用删除项。
页面中员工列表就自动带上了编辑和删除功能。但是目前编辑和删除是采用的文字链接的方式,我想先改成按钮方式:

点击GridView智能标签,选择编辑列,选择选定的字段CommandField,将外观属性ButtonType由Link改成Button,同时可以将该Filed移到表格的最后一列。运行效果如下,使用编辑可以立刻编辑对应的记录,按更新得以更新数据库:
 
员工编号姓名工号部门编号 
0001陈公客10011 
0002王公客10021 
0003张大客30013 
0004李大客30023 

看起来很简单,一切都有系统内置的代码来实现,但是这里面有几个问题:
1.数据库操作冲突,假设A编辑0001号记录,同时B也在编辑,A将工号修改后保存,这时B看到的仍然是原始的记录信息,可能他修改了姓名后也保存。但这是数据库中并非B所期望只修改了姓名。
上面操作截图的第三步:使用开放式并发能够避免这个问题,在上述情况下,B的操作将被取消。因为系统检测到B更新的记录不是最新的,如果B按下更新,那么他的修改将不会进入数据库,并且立刻返回到A修改过的最新员工列表。
2.在系统包办下,所有的数据库操作都没有提示,如果出现更新出错,插入异常,怎么办?
GridView控件提供了很多事件来让我们自定义相应的处理程序。如果想知道更新某条记录是否成功,我们把更新操作返回所影响的行数返回并显示给用户。

单击GridView属性窗口的闪电图标(事件),双击RowUpdated事件行,vs2005创建一个事件处理程序,编写代码如下:
None.gif      protected   void  GridView1_RowUpdated( object  sender, GridViewUpdatedEventArgs e)
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
if (e.ExceptionHandled)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//string exceptionMessage = e.Exception.Message;
ExpandedSubBlockEnd.gif
        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//int numRowsChanged = e.AffectedRows;
InBlock.gif
            foreach (DictionaryEntry myDE in e.NewValues)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
string key = myDE.Key.ToString();
InBlock.gif                
string Val = myDE.Value.ToString();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
//为什么上面的两个变量exceptionMessage,numRowsChanged在下面无法调用?
InBlock.gif        
//比如这样判断 if (numRowsChanged == 0) 就编译出错:当前上下文中不存在名称“numRowsChanged”
InBlock.gif        
//我不太熟悉c#的语法
InBlock.gif
        if (e.AffectedRows == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            textAffectedRows.Text 
= "0";
InBlock.gif            textOpMsg.Text 
= "Error";
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            textOpMsg.Text 
= "OK!";
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif

同时我们在页面中插入两个textbox控件textAffectedRows,textOpMsg用来显示信息,有了这样一个程序,如果更新成功,
返回信息:
影响行数:
如果冲突导致更新失败,显示:
返回信息:
影响行数:

虽然很简单,但是多了一些自己的代码在里面。接下来我再做一下自定义的按钮和动作。 假设页面中有一个HTML <select size=10></select>的列表标签用来存放所选择的员工姓名,我们首先对GridView增加选中和取消选中按钮,再在页面中放置ListBox控件用来显示所选择的员工列表。
对GridView选择列,增加两个ButtonField,Text和CommandName分别对应 "选中""AddSelect"和"取消选中""CancelSelect"
在页面中对GridView增加红色部分,或者在属性中的双击相应的事件:
None.gif<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ClerkID"
None.gif            DataSourceID="SqlDataSource1" BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3" GridLines="Vertical" OnRowUpdated="GridView1_RowUpdated"  OnRowCommand="GridView1_RowCommand">

当点击按钮时,会引发GridView的RowCommand事件,编写代码如下:
None.gif      protected   void  GridView1_RowCommand( object  sender, GridViewCommandEventArgs e)
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif
InBlock.gif        
//取得当前行的索引
InBlock.gif
        int index = Convert.ToInt32(e.CommandArgument);
InBlock.gif        GridViewRow selectedRow 
= GridView1.Rows[index];
InBlock.gif        
//取得该行的员工姓名字段
InBlock.gif
        TableCell clerkName = selectedRow.Cells[1];
InBlock.gif        
//判断按下何按钮
InBlock.gif
        switch (e.CommandName)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
case "AddSelect":
InBlock.gif                ClerkSelectList.Items.Add(clerkName.Text);
InBlock.gif                
break;
InBlock.gif            
case "CancelSelect":
InBlock.gif                
if (ClerkSelectList.Items.Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
int I = 0;
InBlock.gif                    
while (I <= ClerkSelectList.Items.Count - 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
if (ClerkSelectList.Items[I].Text == clerkName.Text)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            ClerkSelectList.Items.Remove(ClerkSelectList.Items[I]);
InBlock.gif                            
break;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            I
++;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
break;
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }
 

上述代码中,e.CommandArgument取得按下ButtonField按钮所在的行索引,通过该索引取得实际的GridViewRow,并用GridViewRow.Cell[1]取得字段值。e.Commandname用来区分用户按下了哪个ButtonField按钮,运行结果就不截图了。

如果我们要自定义按钮的显示,比如按钮显示选中-后面跟上员工的名字,可以设置按钮的DataTextField和DataTextFormatString属性:


这样显示的结果就相当个性化了,提示也非常明显:
员工编号姓名工号部门编号 按钮字段一 按钮字段二 
0001陈公客10011 
0002王公客10021 
0003张大客30013 
0004李大客30023 

接下来应该学习最有作用的CommandField命令按钮字段了,虽然外观看起来和ButtonField一样,但是CommandField内置了Select,Edit,Update,Delete和Insert的命令。操作数据库得用好他们。

转载于:https://www.cnblogs.com/hulu/archive/2007/06/29/800769.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值