Visual Studio và Data Access – Phần 3

Khi các attribute được thêm vào một phần tử, một thuộc tính được thêm vào

lớp DataRownhư ở trên. Thuộc tính có cùng tên như attribute, vì thế trong

ví dụ trên cho hàng Product, có các thuộc tính như Name, SKU, Description,

và Price.

Để mọi attribute thêm vào, sự thay đổi được tạo trong tập tin.cs. Trong ví dụ

bên dưới sẽ chỉ ta thêm một attribute gọi là ProductID

pdf14 trang | Chuyên mục: Visual C# | Chia sẻ: dkS00TYs | Lượt xem: 1620 | Lượt tải: 2download
Tóm tắt nội dung Visual Studio và Data Access – Phần 3, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
Viewing .NET Data 
Visual Studio và Data Access – Phần 3 
Tạo DataRow 
Lớp ProductRow được tạo như trình bày bên dưới: 
public class ProductRow : DataRow 
{ 
 private ProductDataTable tableProduct; 
 internal ProductRow(DataRowBuilder rb) : base(rb) 
 { 
 this.tableProduct = ((ProductDataTable)(this.Table)); 
 } 
 public string Name { ... } 
 public bool IsNameNull { ... } 
 public void SetNameNull { ... } 
 // Other accessors/mutators omitted for clarity 
} 
Khi các attribute được thêm vào một phần tử, một thuộc tính được thêm vào 
lớp DataRow như ở trên. Thuộc tính có cùng tên như attribute, vì thế trong 
ví dụ trên cho hàng Product, có các thuộc tính như Name, SKU, Description, 
và Price. 
Để mọi attribute thêm vào, sự thay đổi được tạo trong tập tin.cs. Trong ví dụ 
bên dưới sẽ chỉ ta thêm một attribute gọi là ProductID 
Lớp ProductDataTable đầu tiên có một thành viên riêng được thêm là 
DataColumn: 
private DataColumn columnProductId; 
Nó được tham gia bởi một thuộc tính có tên ProductIDColumn : 
internal DataColumn ProductIdColumn 
{ 
 get { return this.columnProductId; } 
} 
Phương thức AddProductRow() trình bày ở trên được sửa đổi, nó mang một 
ProductId số nguyên và lưu trữ giá trị trong một cột được tạo mới: 
public ProductRow AddProductRow ( ... , int ProductId) 
{ 
 ProductRow rowProductRow = ((ProductRow)(this.NewRow())); 
 rowProductRow.ItemArray = new Object[] { ... , ProductId}; 
 this.Rows.Add(rowProductRow); 
 return rowProductRow; 
} 
Cuối cùng, trong ProductDataTable, có một sự sửa đổi đến phương thức 
InitClass(): 
private void InitClass() 
{ 
 ... 
 this.columnProductID = new DataColumn("ProductID", typeof(int), null, 
 System.Data.MappingType.Attribute); 
 this.Columns.Add(this.columnProductID); 
 this.columnProductID.Namespace = ""; 
} 
Nó tạo DataColumn mới và thêm nó vào Columns Collection của 
DataTable. Tham số cuối cùng cho hàm dựng DataColumn định nghĩa cách 
cột này được vẽ lên XML. Điều này có lợi khi DataSet được lưu vào một tập 
tin XML 
Lớp ProductRow được cập nhật để thêm một bộ truy cập cho cột này: 
public int ProductId 
{ 
 get { return ((int)(this[this.tableProduct.ProductIdColumn])); } 
 set { this[this.tableProduct.ProductIdColumn] = value; } 
} 
Tạo EventArgs 
Lớp cuối cùng được thêm vào mã nguồn là một sự thừa hưởng của 
EventArgs, lớp này cung cấp các phương thức truy cập trực tiếp vào hàng đã 
được thay đổi, và hành động được áp dụng vào hàng đó. Đoạn mã này đã bị 
xoá cho ngắn gọn hơn. 
Những yêu cầu khác 
Một yêu cầu chung khi hiển thị dữ liệu là cung cấp một menu Pop-up cho 
một hàng. Có nhiều cách để thực hiện nhưng ta tập trung vào một cách có 
thể đơn giản các đoạn mã được yêu cầu, Nếu phạm vi hiển thị là một 
DataGrid, nơi có một DataSet với vài mối quan hệ được hiển thị. Vấn đề ở 
đây là menu ngữ cảnh phụ thuộc vào hàng đang được chọn, và hàng đó có 
thể đến từ bất kỳ DataTable nguồn nào trong DataSet. 
Chức năng của menu ngữ cảnh thì thích hợp để đạt mục đích chung, sự thực 
thi ở đây sử dụng một lớp cơ sở để hổ trợ một menu pop-up thừa hưởng từ 
lớp cơ sở này. 
Khi người dùng click phải trên bất kỳ phần nào của một hàng trong 
DataGrid, chúng ta sẽ tìm kiếm hàng và kiểm tra nếu nó thừa hưởng từ 
ContextDataRow và phương thức PopupMenu() có thể được gọi. Bạn nên 
thực thi nó bằng cách sử dụng một giao diện nhưng trong thể hiện này một 
lớp cơ sở thì đơn giản hơn. 
Ví dụ này sẽ chỉ cách để tạo các lớp DataRow và Datatable, các lớp này có 
thể sử dụng để cung cấp truy cập type-safe đến dữ liệu. 
Minh hoạ bên dưới trình bày thừa kế lớp cho ví dụ này: 
Đoạn mã đầy đủ nằm trong thư mục 11_Miscellaneous: 
using System; 
using System.Windows.Forms; 
using System.Data; 
using System.Data.SqlClient; 
using System.Reflection; 
public class ContextDataRow : DataRow 
{ 
 public ContextDataRow(DataRowBuilder builder) : base(builder) 
 { 
 } 
 public void PopupMenu(System.Windows.Forms.Control parent, int x, int 
y) 
 { 
 // Use reflection to get the list of popup menu commands 
 MemberInfo[] members = this.GetType().FindMembers 
(MemberTypes.Method, 
 BindingFlags.Public | BindingFlags.Instance , 
 new System.Reflection.MemberFilter(Filter), 
 null); 
 if (members.Length > 0) 
 { 
 // Create a context menu 
 ContextMenu menu = new ContextMenu(); 
 // Now loop through those members and generate the popup menu 
 // Note the cast to MethodInfo in the foreach 
 foreach (MethodInfo meth in members) 
 { 
 // Get the caption for the operation from the 
 // ContextMenuAttribute 
 ContextMenuAttribute[] ctx = (ContextMenuAttribute[]) 
 meth.GetCustomAttributes(typeof(ContextMenuAttribute), true); 
 MenuCommand callback = new MenuCommand(this, meth); 
 MenuItem item = new MenuItem(ctx[0].Caption, new 
 EventHandler(callback.Execute)); 
 item.DefaultItem = ctx[0].Default; 
 menu.MenuItems.Add(item); 
 } 
 System.Drawing.Point pt = new System.Drawing.Point(x,y); 
 menu.Show(parent, pt); 
 } 
 } 
 private bool Filter(MemberInfo member, object criteria) 
 { 
 bool bInclude = false; 
 // Cast MemberInfo to MethodInfo 
 MethodInfo meth = member as MethodInfo; 
 if (meth != null) 
 if (meth.ReturnType == typeof(void)) 
 { 
 ParameterInfo[] parms = meth.GetParameters(); 
 if (parms.Length == 0) 
 { 
 // Lastly check if there is a ContextMenuAttribute on the 
 // method... 
 object[] atts = meth.GetCustomAttributes 
 (typeof(ContextMenuAttribute), true); 
 bInclude = (atts.Length == 1); 
 } 
 } 
 return bInclude; 
 } 
} 
Lớp hàng dữ liệu ngữ cảnh được thừa hưởng từ DataRow, và chứa hai chức 
năng thành viên. Đầu tiên là PopupMenu dùng sự phản ánh để tìm các 
phương thức phù hợp với một dạng cụ thể, và nó hiện một menu pop-up của 
những tuỳ chọn này đến người dùng. phương thức Filter() được dùng như 
một đại diện bởi PopupMenu khi liệt kê các phương thức. Nó trả về kết quả 
true nếu chức năng thành viên thực hiện tương ứng với quy ước gọi: 
 MemberInfo[] members = 
this.GetType().FindMembers(MemberTypes.Method, 
 BindingFlags.Public | BindingFlags.Instance, 
 new System.Reflection.MemberFilter(Filter), 
 null); 
Statement này được dùng để lọc tất cả phương thức trên đối tượng hiện 
hành, và chỉ trả về theo các tiêu chuẩn sau: 
 Thành viên phải là một phương thức 
 Thành viên phải là một phương thức thể hiện public 
 Thành viên không có kiểu trả về 
 Thành viên phải chấp nhận không tham số 
 Thành viên phải bao gồm ContextMenuAttribute 
Cuối cùng là một custom attribute, chúng ta sẽ bàn luần về nó sau khi tìm 
hiểu rõ phương thức PopupMenu. 
ContextMenu menu = new ContextMenu(); 
foreach (MethodInfo meth in members) 
{ 
 // ... Add the menu item 
} 
System.Drawing.Point pt = new System.Drawing.Point(x,y); 
menu.Show(parent, pt); 
Một thể hiện menu ngữ cảnh được tạo, và chúng ta lặp qua mọi phương thức 
theo tiêu chuẩn trên và thêm mục vào menu. Menu được hiển thị như trình 
bày trong màn hình sau: 
Rắc rối chính của ví dụ này là phần mã sau, lập lại một lần cho mọi chức 
năng thành viên để được hiển thị trên pop-up menu. 
System.Type ctxtype = typeof(ContextMenuAttribute); 
ContextMenuAttribute[] ctx = (ContextMenuAttribute[]) 
 meth.GetCustomAttributes(ctxtype); 
MenuCommand callback = new MenuCommand(this, meth); 
MenuItem item = new MenuItem(ctx[0].Caption, 
 new EventHandler(callback.Execute)); 
item.DefaultItem = ctx[0].Default; 
menu.MenuItems.Add(item); 
Mọi phương thức nên trình bày trên menu ngữ cảnh được tượng trưng với 
ContextMenuAttribute. Định nghĩa này là một tên người dùng quen thuộc 
cho các tuỳ chọn menu, như một tên phương thức C# không thể bao gồm các 
khoảng trắng. Attribute được khôi phục từ phương thức và một mục menu 
mới được tạo và thêm vào tập hợp mục memu của pop-up menu. 
Ví dụ này cũng trình bày cách dùng của một lớp Command đơn giản. Lớp 
MenuCommand dùng trong thể hiện này được trigger từ người dùng chọn 
một mục trên menu ngữ cảnh, và nó định dạng việc gọi đến bộ nhận của 
phương thức. 

File đính kèm:

  • pdf92_4041.pdf
Tài liệu liên quan