不多說,還是直接看最終的效果:(沒有選中記錄的初始效果)
選中的效果:
切換數據庫的效果:
對應的設計視圖:(Default.aspx主要就是:GridView控件+DetailsView控件+ObjectDataSource控件)
實現了部門和用戶的管理(增/刪/改),而后置代碼(default.aspx.cs只有七行代碼,就實現了!)可以說,三層的開發尤其是BLL業務域對象的封裝,使得UI的開發變得簡易多了,由於WebUI控件的數據綁定和相互良好的關聯,比起UI桌面版開發更顯簡單。文章的后面再講解數據分頁的實現功能。
最后一個<切換數據庫ImageButton> 也是僅僅為了演示方便,實現動態更改配置文件web.config對應節點的功能。
下面介紹實現的過程:
DAL和BLL文件夾的編碼過程參考DAL編碼實現和BLL編碼實現,這里不再重復。
設計視圖GridView和DetailsView是沒有應用樣式的(看起來也清爽些),運行的時候的樣式應用來自於主題文件夾SkinGrid下的Controls.skin設置。
(關於主題方面的應用請參考主題設計)
Controls.skin的設置:

1 <asp:TextBox runat="server" BorderStyle="dashed" BorderWidth="1px" />
2
3 <asp:GridView runat="server" Width="100%" CellPadding="4" ForeColor="#333333" GridLines="None">
4 <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
5 <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
6 <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
7 <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
8 <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
9 <AlternatingRowStyle BackColor="White" />
10 </asp:GridView>
11
12 <asp:DetailsView runat="server" CellPadding="4"
13 ForeColor="#333333" GridLines="None" Height="50px" Width="100%">
14 <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
15 <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
16 <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
17 <AlternatingRowStyle BackColor="White" />
18 <CommandRowStyle BackColor="#fbfbd9" Font-Bold="True" HorizontalAlign="Right" />
19 <RowStyle BackColor="White" />
20 <FieldHeaderStyle BackColor="#fbfbd9" Font-Bold="True" />
21 </asp:DetailsView>
顯示部門列表的GridView控件gvDepts的設置過程:(注意序號的順序)
上圖主要針對數據源的配置(ObjectDataSource)---接下來針對GridView控件本身的列進行設置。
gvDepts一共3列,一列模板字段(可以自己定義顯示),后兩列命令按鈕的ButtonType都設置為圖片類型。
在模板列Column[0]中放置兩個Literal控件(Label控件也行),設置Text的綁定為Name和Desc。
為了能馬上運行看到效果:還要在web.config配置一下,和桌面版UI的app.config配置相同,見圖:
運行的效果:
接下來實現:當選中一行部門記錄時(這里的選擇按鈕(筆狀的圖標)),用DetailsView控件(dvDept)顯示對應的詳細信息。
其odsDept的設計視圖對應為:

1 <asp:ObjectDataSource ID="odsDept" runat="server"
2 InsertMethod="InsertDepartmentObj" SelectMethod="GetDepartmentById"
3 TypeName="抽象工廠模式.BLL.DepartmentObj" UpdateMethod="UpdateDepartmentObj">
4 <InsertParameters>
5 <asp:Parameter Name="name" Type="String" />
6 <asp:Parameter Name="desc" Type="String" />
7 </InsertParameters>
8 <SelectParameters>
9 <asp:ControlParameter ControlID="gvDepts" Name="id"
10 PropertyName="SelectedValue" Type="Int32" />
11 </SelectParameters>
12 <UpdateParameters>
13 <asp:Parameter Name="id" Type="Int32" />
14 <asp:Parameter Name="name" Type="String" />
15 <asp:Parameter Name="desc" Type="String" />
16 </UpdateParameters>
17 </asp:ObjectDataSource>
后續的GridView控件gvUsers和DetaisView控件dvUser的類似設置不再給出圖片,直接給代碼設置,相信能看明白了。
這些控件的EmptyDataText屬性用來顯示當沒有記錄時的文本信息!如果需要更豐富的顯示,可使用EmptyDataTemplate定制。
每個GridView的DataKeyNames=Id和DetailsView的DataField=Id。
考慮到顯示主鍵沒有意義,所以Id字段的visible屬性設置為False(或則去掉該列)。Name字段必須要進行非空驗證,所以該列應轉換為模板列。
通常來說:DetailsView的每一列都轉換成TemplateField會更實用方便。(注意模板列字段與綁定字段在圖標顯示上的不同)
注意驗證控件及按鈕控件都有的ValidationGroup屬性,非常有用的!后面會用到。
將開始模式設置為:Insert,這樣便於顯示。(因為一開始運行並沒有選中gvDepts控件。)
當選中gvDepts中的一條記錄時,dvDept應該切換為編輯模式(Edit模式),而且插入新部門和更新當前部門信息時,gvDepts的數據應該刷新。
測試通過,但是點擊“垃圾桶”按鈕刪除時,沒有確認提示!
當初數據庫設計時,外鍵關系是層疊更新和刪除,這意味着該部門記錄刪除時其子表User的對應記錄一並刪除,所以確認不可少,同時為了減少誤操作!
將gvDepts的刪除命令按鈕轉為成模板列字段,GridView編輯模板Columns[2],在ItemTemplate中找到ImageButton,設置其OnClientClick屬性。
運行測試正常,后續的gvUsers[GridView]和dvUser類似上面的圖形操作。直接看代碼截圖:
運行的時候,會出現一個問題,如下圖所示:
由於dvDept的插入按鈕會執行驗證激活,所以dvUser的名稱文本框被激活,導致插入失效。
通過設置驗證控件和命令按鈕的ValidationGroup設置實現組區分驗證。很顯然:dvDept內部和dvUser是兩組獨立的驗證,只要設置該屬性不同即可。
最后:切換數據庫按鈕的核心代碼
頁面代碼:
default.aspx設計視圖主要代碼:

1 <form id="form1" runat="server">
2 <div>
3 <div>管理部門</div>
4 <asp:GridView ID="gvDepts" runat="server" DataSourceID="odsDepts"
5 EnableModelValidation="True" DataKeyNames="Id" AutoGenerateColumns="False"
6 onselectedindexchanged="gvDepts_SelectedIndexChanged" Width="500px"
7 EmptyDataText="沒有部門信息">
8 <Columns>
9 <asp:TemplateField>
10 <ItemTemplate>
11 <div><b>
12 <asp:Literal ID="lblName" Text='<%#Eval("Name") %>' runat="server"></asp:Literal></b></div>
13 <asp:Literal ID="lblDesc" Text='<%#Eval("Desc") %>' runat="server"></asp:Literal>
14 <ItemStyle HorizontalAlign="Center" Width="200px" />
15 </ItemTemplate>
16 </asp:TemplateField>
17 <asp:CommandField ButtonType="Image" SelectImageUrl="~/images/Edit.gif"
18 SelectText="編輯部門" ShowSelectButton="True" >
19 <ItemStyle HorizontalAlign="Center" Width="20px" />
20 </asp:CommandField>
21 <asp:TemplateField ShowHeader="False">
22 <ItemTemplate>
23 <asp:ImageButton ID="btnDeleteDept" OnClientClick="return confirm('是否想刪除該部門?');" runat="server" CausesValidation="False"
24 CommandName="Delete" ImageUrl="~/images/Delete.gif" Text="刪除部門" />
25 </ItemTemplate>
26 <ItemStyle HorizontalAlign="Center" Width="20px" />
27 </asp:TemplateField>
28
29 </Columns>
30 </asp:GridView>
31 <asp:ObjectDataSource ID="odsDepts" runat="server"
32 SelectMethod="GetDepartments" TypeName="抽象工廠模式.BLL.DepartmentObj"
33 DeleteMethod="DeleteDepartmentObj">
34 <DeleteParameters>
35 <asp:Parameter Name="id" Type="Int32" />
36 </DeleteParameters>
37 </asp:ObjectDataSource>
38 </div>
39 <table border="0" width="100%" cellpadding="0" cellspacing="0">
40 <tr><td width="30%">
41 <asp:ObjectDataSource ID="odsDept" runat="server"
42 InsertMethod="InsertDepartmentObj" SelectMethod="GetDepartmentById"
43 TypeName="抽象工廠模式.BLL.DepartmentObj" UpdateMethod="UpdateDepartmentObj">
44 <InsertParameters>
45 <asp:Parameter Name="name" Type="String" />
46 <asp:Parameter Name="desc" Type="String" />
47 </InsertParameters>
48 <SelectParameters>
49 <asp:ControlParameter ControlID="gvDepts" Name="id"
50 PropertyName="SelectedValue" Type="Int32" />
51 </SelectParameters>
52 <UpdateParameters>
53 <asp:Parameter Name="id" Type="Int32" />
54 <asp:Parameter Name="name" Type="String" />
55 <asp:Parameter Name="desc" Type="String" />
56 </UpdateParameters>
57 </asp:ObjectDataSource>
58 <asp:DetailsView ID="dvDept" runat="server" AutoGenerateRows="False"
59 DataSourceID="odsDept" EnableModelValidation="True" HeaderText="部門詳細信息"
60 Height="50px" Width="207px" DataKeyNames="Id" DefaultMode="Insert"
61 ondatabound="dvDept_DataBound" EmptyDataText="沒有部門信息">
62 <Fields>
63 <asp:BoundField DataField="Id" HeaderText="Id" ReadOnly="True"
64 SortExpression="Id" Visible="False" />
65 <asp:TemplateField HeaderText="名稱" SortExpression="Name">
66 <EditItemTemplate>
67 <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
68 <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
69 ControlToValidate="TextBox1" ValidationGroup="edtDept" ErrorMessage="名稱不能為空!">*</asp:RequiredFieldValidator>
70 </EditItemTemplate>
71 <InsertItemTemplate>
72 <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
73 <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
74 ControlToValidate="TextBox1" ValidationGroup="edtDept" ErrorMessage="名稱不能為空!">*</asp:RequiredFieldValidator>
75 </InsertItemTemplate>
76 <ItemTemplate>
77 <asp:Label ID="Label1" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
78 </ItemTemplate>
79 </asp:TemplateField>
80 <asp:BoundField DataField="Desc" HeaderText="描述" SortExpression="Desc" />
81 <asp:CommandField ValidationGroup="edtDept" ShowEditButton="True" ShowInsertButton="True" />
82 </Fields>
83 </asp:DetailsView></td><td width="2%"></td>
84 <td width="68%">
85 <div>管理用戶</div>
86 <asp:GridView ID="gvUsers" runat="server" AutoGenerateColumns="False"
87 DataSourceID="odsUsers" EnableModelValidation="True" DataKeyNames="Id"
88 onselectedindexchanged="gvUsers_SelectedIndexChanged"
89 EmptyDataText="沒有用戶信息!">
90 <Columns>
91 <asp:BoundField DataField="Name" HeaderText="名稱" SortExpression="Name" />
92 <asp:BoundField DataField="DeptTitle" HeaderText="部門"
93 SortExpression="DeptTitle" />
94 <asp:CommandField ShowSelectButton="True" ButtonType="Image"
95 SelectImageUrl="~/images/Edit.gif" SelectText="編輯用戶" />
96 <asp:TemplateField ShowHeader="False">
97 <ItemTemplate>
98 <asp:ImageButton ID="ImageButton1" runat="server" CausesValidation="False"
99 CommandName="Delete" ImageUrl="~/images/Delete.gif" Text="刪除用戶"
100 OnClientClick="return confirm('是否刪除該用戶?');" />
101 </ItemTemplate>
102 </asp:TemplateField>
103 </Columns>
104 </asp:GridView>
105 <asp:ObjectDataSource ID="odsUsers" runat="server" DeleteMethod="DeleteUserObj"
106 SelectMethod="GetUsers" TypeName="抽象工廠模式.BLL.UserObj">
107 <DeleteParameters>
108 <asp:Parameter Name="id" Type="Int32" />
109 </DeleteParameters>
110 <SelectParameters>
111 <asp:ControlParameter ControlID="gvDepts" Name="deptId"
112 PropertyName="SelectedValue" Type="Int32" />
113 </SelectParameters>
114 </asp:ObjectDataSource><br />
115 <asp:DetailsView ID="dvUser" runat="server" Height="50px" Width="218px"
116 AutoGenerateRows="False" DataKeyNames="Id" DataSourceID="odsUser"
117 EnableModelValidation="True" HeaderText="用戶信息" DefaultMode="Insert"
118 ondatabound="dvUser_DataBound" EmptyDataText="沒有用戶信息!">
119 <Fields>
120 <asp:TemplateField HeaderText="名稱" SortExpression="Name">
121 <EditItemTemplate>
122 <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
123 <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
124 ControlToValidate="TextBox2" ValidationGroup="edtUser" ErrorMessage="名稱不能為空!">*</asp:RequiredFieldValidator>
125 </EditItemTemplate>
126 <InsertItemTemplate>
127 <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
128 <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
129 ControlToValidate="TextBox2" ValidationGroup="edtUser" ErrorMessage="名稱不能為空!">*</asp:RequiredFieldValidator>
130 </InsertItemTemplate>
131 <ItemTemplate>
132 <asp:Label ID="Label2" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
133 </ItemTemplate>
134 </asp:TemplateField>
135 <asp:TemplateField HeaderText="部門" SortExpression="DeptId">
136 <EditItemTemplate>
137 <asp:DropDownList ID="cboDepts" runat="server" DataSourceID="odsSelectDept"
138 DataTextField="Name" DataValueField="Id"
139 SelectedValue='<%# Bind("DeptId") %>'>
140 </asp:DropDownList>
141 </EditItemTemplate>
142 <InsertItemTemplate>
143 <asp:DropDownList ID="cboDepts" runat="server" DataSourceID="odsSelectDept"
144 DataTextField="Name" DataValueField="Id"
145 SelectedValue='<%# Bind("DeptId") %>'>
146 </asp:DropDownList>
147 </InsertItemTemplate>
148 <ItemTemplate>
149 <asp:Label ID="Label1" runat="server" Text='<%# Eval("DeptTitle") %>'></asp:Label>
150 </ItemTemplate>
151 </asp:TemplateField>
152 <asp:CommandField ValidationGroup="edtUser" ShowEditButton="True" ShowInsertButton="True" />
153 </Fields>
154 </asp:DetailsView>
155 <asp:ObjectDataSource ID="odsUser" runat="server" InsertMethod="InsertUserObj"
156 SelectMethod="GetUserById" TypeName="抽象工廠模式.BLL.UserObj"
157 UpdateMethod="UpdateUserObj">
158 <InsertParameters>
159 <asp:Parameter Name="deptId" Type="Int32" />
160 <asp:Parameter Name="name" Type="String" />
161 </InsertParameters>
162 <SelectParameters>
163 <asp:ControlParameter ControlID="gvUsers" Name="id"
164 PropertyName="SelectedValue" Type="Int32" />
165 </SelectParameters>
166 <UpdateParameters>
167 <asp:Parameter Name="id" Type="Int32" />
168 <asp:Parameter Name="name" Type="String" />
169 <asp:Parameter Name="deptId" Type="Int32" />
170 </UpdateParameters>
171 </asp:ObjectDataSource>
172 <asp:ObjectDataSource ID="odsSelectDept" runat="server"
173 SelectMethod="GetDepartments" TypeName="抽象工廠模式.BLL.DepartmentObj">
174 </asp:ObjectDataSource>
175 </td>
176 </tr>
177 </table>
178 <hr />
179 <asp:ImageButton ID="btnChangeDB" runat="server" ImageUrl="~/images/Write.gif"
180 onclick="btnChangeDB_Click" style="height: 16px" />
181 切換數據庫</form>
Default.aspc.cs代碼:

1 public partial class _Default : System.Web.UI.Page
2 {
3
4 protected void gvDepts_SelectedIndexChanged(object sender, EventArgs e)
5 {
6 dvDept.ChangeMode(DetailsViewMode.Edit);
7 }
8
9 protected void dvDept_DataBound(object sender, EventArgs e)
10 {
11 gvDepts.DataBind();
12 dvUser.DataBind();
13 }
14
15 protected void gvUsers_SelectedIndexChanged(object sender, EventArgs e)
16 {
17 dvUser.ChangeMode(DetailsViewMode.Edit);
18 }
19
20 protected void dvUser_DataBound(object sender, EventArgs e)
21 {
22 gvUsers.DataBind();
23 }
24
25 protected void btnChangeDB_Click(object sender, ImageClickEventArgs e)
26 {
27 抽象工廠模式.Helper.ChangeConfiguration();
28 DataBind();
29 }
30 protected void Page_Load(object sender, EventArgs e)
31 {
32
33 }
34 }
Helper.cs代碼:

1 class Helper
2 {
3 private static string ProviderType = ConfigurationManager.AppSettings["ProviderType"];
4 private static string DBConnString =
5 ConfigurationManager.ConnectionStrings["DBConnString"].ConnectionString;
6
7 private static void SetConfig()
8 {
9 if (ProviderType.ToLower() == "sql")
10 {
11 ProviderType = "Access";
12 DBConnString =
13 @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\netStudy\抽象工廠模式\testdb.mdb";
14 }
15 else
16 {
17 ProviderType = "Sql";
18 DBConnString = @"Data Source=.\sqlexpress;Initial Catalog=testdb;Integrated Security=True";
19 }
20 }
21
22 public static void ChangeConfiguration()
23 {
24
25 SetConfig(); //讀取程序集的配置文件
26
27 var config =
28 System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
29
30 //獲取appSettings節點
31 AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("appSettings");
32 appSettings.Settings["ProviderType"].Value = ProviderType;
33
34 var connectionSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
35 connectionSection.ConnectionStrings["DBConnString"].ConnectionString = DBConnString;
36
37 //保存配置文件
38 config.Save();
39 }
40 }