Hiển thị kết quả từ 1 đến 10 / 15
Chủ đề: Sử Dụng Datagrid.Net (Phần I)
-
12-01-2003 10:42 #1
[TUTOR] Sử Dụng Datagrid.Net (Phần I)
Sử Dụng DataGrid Trong .Net để có một giao diện chuyên nghiệp (Phần I)
Đây là một bài viết dài (Sorry) nhưng rất chi tiết và đầy đủ - Bạn co thể download file .zip có bài viết này dưới dạng .doc với đầy đủ hình ảnh và source code
Có lẽ bất kỳ ai đã từng lập trình CSDL trong Access cũng đều phải thừa nhận sự dễ dàng trong thiết kế giao diện. Đặc biệt là khi sử dụng các Grid với các ComboBox phát sinh tự động (miễn là bạn định nghĩa trường Lookup trong khi thiết kế các Table).
Lập trình CSDL trong Visual Basic có nghĩa là bạn phải làm “thủ công” mọi chuyện. Có lẽ không có kỹ thuật nào hay thay đổi như kỹ thuật truy cập dữ liệu của Microsoft, từ RDO, đến ADO, và hiện nay là ADO.Net – điều đó có nghĩa là bạn phải luôn cập nhật, đổi mới cách lập trình của mình. Dù sao, .Net cũng là một bước nhảy lớn trong kỹ thuật lập trình và có lẽ cũng đáng để mắt một chút tới các thay đổi trong CSDL và các Control liên quan. Trong loạt bài này (hưởng ứng “Chương Trình Sao” của Sticky) tôi mong muốn chia sẻ một số kinh nghiệm khi sử dụng DataGrid, một công cụ không thể thiếu trong lập trình CSDL để giúp bạn có được một công cụ uyển chuyển và mạnh.
Tuy nhiên, đây chỉ là kỹ thuật nền tảng, không phải là giải pháp tối ưu vì vậy rất mong được sự góp ý thêm của các bạn và, nếu có thể, cùng nhau tạo ra các control đóng gói (thành các class) giúp giảm thời gian coding cho mọi nguời.
1. Giới thiệu về Datagrid.Net
Khi lập trình CSDL trong VB6, hiếm khi các nhà phát triển sử dụng Datagrid có sẵn của Microsoft mà thường phải dùng các Grid thương mại của các third-party (như FlexGrid, TrueDBGrid, Janus GridEX…) vì nó thiếu các chức năng cao cấp như tạo các cột có chứa hình ảnh, có các Drop-down combo…
Ấn tượng đầu tiên khi tiếp xúc với Datagrid của .Net là dường như nó không có gì thay đổi cả, vẫn chỉ là các cột “cứng” dùng để hiển thị các dữ liệu thô trong các bảng CSDL. Khi sử dụng các Grid dưới dạng các ActiveX trong .Net dữ liệu thường không được hiển thị tốt (nhất là khi cần định dạng) và nói chung các ActiveX control chạy không tốt lắm trong môi trường .Net, đa số lại không hỗ trợ Unicode - một tính năng tối cần thiết cho các LTV Việt Nam. Chính vì thế tôi phải quay về với Datagrid của .Net và thật may mắn tôi tìm thấy một số bài viết về cách mở rộng chức năng của nó trên Internet. Thì ra khác với vẻ ngoài của mình, Datagrid.Net là một Grid “mở”, bạn có thể:
[list = 1][*] Định dạng dữ liệu cho từng cột (kg có gì mới)[*] Các cột có thể là bound (tức là gắn với một field dữ liệu trong bảng) hay unbound (cột độc lập với dữ liệu - rất tốt khi để hiển thị các trường tính toán hay các trường định dạng đặc biệt)[*] Gắn các control khác vào mỗi cột (như Combobox, Datetimepicker…)[*] Và một chức năng cao cấp khác là tạo ra hẳn một Style Column - dạng cột mới.[/list = 1]
Trong Datagrid.Net chỉ có hai ColumnStyle được build-in là: Textbox ColumnStyle và Checkbox ColumnStyle. Chắc các bạn cũng đoán ra chức năng của hai dạng cột này, một là để hiển thị các dữ liệu dạng text hay date/time, và cái kia là để hiển thị dữ liệu false/true dưới hình thức các checkbox. Một giải pháp hoàn chỉnh có lẽ là tạo ra các dạng cột mới để hiển thị các dữ liệu theo ý mình, nhưng nó đòi hỏi bạn phải viết các Class, events… mới khá phức tạp (tôi sẽ viết về vấn đề này trong một bài riêng). Tuy nhiên, ở mức độ phát triển ứng dụng nhanh và nếu bạn muốn tác động trực tiếp tới các hành vi của Datagrid.Net thì tốt nhất là bạn sử dụng ngay những cái có sẵn – chúng đủ mạnh cho hầu hết các chức năng thông thường. Trong phần sau, tôi sẽ trình bày một số kỹ thuật/thủ thuật để bạn có thể tạo ra các cột có chứa Combobox, Checkbox, Date Picker, hình ảnh và cho ẩn dấu các cột không cần thiết.
2. Tạo cột có chứa Combobox, Checkbox
Note:
- Để đơn giản hoá việc truy cập dữ liệu, các ví dụ ở đây đều sử dụng các table trong CSDL Access Northwind.mdb (bạn có thể tìm thấy CSDL này trong thư mục Samples của bộ Office)
- Trong phần này tôi giả sử bạn đã biết về lập trình CSDL trong VB.Net và sẽ không giải thích thêm về các khái niệm như data connection, data adapter hay dataset…
Bước 1: Tạo một dự án mới có tên FlexibleDatagrid trong Visual Basic.Net, đổi tên của Form1 thành “frmProducts” và Text (caption) thành “Product Grid”.
Bước 2: Tạo Dataset có chứa table “Products” là datasource cho Grid: Thêm vào một OleDataAdapter1, khi wizard hiện lên bạn kết nối vào CSDL Northwind.mdb, chọn table “Products”, SELECT các fields: ProductID, ProductName, SupplierID, QualityPerUnit, UnitPrice và Discontinued. Trong phần “Advanced Options…” bạn nhớ đánh dấu hộp kiểm “Generate Insert, Update, Delete statements” (mặc định), sau đó phát sinh (generate) table “Products” vào Dataset1.
Bước 3: Tạo table “Suppliers” dùng để làm datasource cho Combobox: Thêm vào một OleDataAdapter2, khi wizard hiện lên bạn kết nối vào CSDL Northwind.mdb, chọn table “Suppliers”, SELECT các fields: SupplierID, CompanyName. Trong phần “Advanced Options…” bỏ dấu hộp kiểm “Generate Insert, Update, Delete statements”, sau đó phát sinh (generate) table Suppliers vào Dataset1.
Bước 4: Thêm vào form một Datagrid control và đổi tên nó thành dgdProducts, đặt Dock = Fill để nó nở ra chiếm hết form.
Bước 5: Thêm vào các thủ tục để connect với database, nạp dữ liệu vào Dataset (Microsoft way):
Gọi thủ tục LoadDataset vào lúc load form:Code:Private Sub LoadDataset() 'Create a new dataset to hold the records returned from the call to FillDataSet. 'A temporary dataset is used because filling the existing dataset would 'require the databindings to be rebound. Dim objDatasetTemp As FlexibleDatagrid.DataSet1 objDatasetTemp = New FlexibleDatagrid.DataSet1() Try 'Attempt to fill the temporary dataset. Me.FillDataSet(objDatasetTemp) Catch eFillDataset As Exception Throw eFillDataset End Try Try 'Empty the old records from the dataset. DataSet11.Clear() 'Merge the records into the main dataset. DataSet11.Merge(objDatasetTemp) Catch eLoadMerge As Exception Throw eLoadMerge End Try End Sub Private Sub FillDataset(ByVal dataSet As FlexibleDatagrid.DataSet1) 'Turn off constraint checking before the dataset is filled. 'This allows the adapters to fill the dataset without concern 'for dependencies between the tables. dataSet.EnforceConstraints = False Try 'Open the connection. Me.OleDbConnection1.Open() 'Attempt to fill the dataset through the OleDbDataAdapter1. Me.OleDbDataAdapter1.Fill(dataSet) 'Attempt to fill the dataset through the OleDbDataAdapter2. Me.OleDbDataAdapter2.Fill(dataSet) Catch fillException As System.Exception 'Add your error handling code here. Throw fillException Finally 'Turn constraint checking back on. dataSet.EnforceConstraints = True 'Close the connection whether or not the exception was thrown. Me.OleDbConnection1.Close() End Try End Sub
Bước 6: Tạo một Combobox, fill với dữ liệu từ table “Suppliers” và gằn Combobox này vào cột SupplierIDCode:Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) Try LoadDataset() Catch loaddataException As Exception MessageBox.Show(loaddataException.Message) 'Close form if there is error in loading data Me.Close() End Try End Sub
Tạo hai biến chung chứa các table Products và Suppliers:
Tạo một thủ tục có tên PopulateGrid() và thêm vào đoạn mã sau:Code:Dim tblProducts, tblSuppliers As DataTable
Cuối cùng bạn gọi thủ tục này sau khi load dataset:Code:Private Sub PopulateGrid() tblProducts = DataSet11.Tables("Products") tblSuppliers = DataSet11.Tables("Suppliers") 'Create new ComboBox, fill it with data from table "Suppliers" Dim cboSupplier As New ComboBox() With cboSupplier .DropDownStyle = ComboBoxStyle.DropDownList .Dock = DockStyle.Fill .DataSource = tblSuppliers .ValueMember = tblSuppliers.Columns(0).ToString .DisplayMember = tblSuppliers.Columns(1).ToString End With 'set style property when first time the grid loads, next time onwards it 'will maintain its property If (Not dgdProducts.TableStyles.Contains("Products")) Then 'Create a DataGridTableStyle object Dim dgdtblStyle As New DataGridTableStyle() 'Set its properties dgdtblStyle.MappingName = tblProducts.TableName 'its table name of dataset dgdProducts.TableStyles.Add(dgdtblStyle) dgdtblStyle.AlternatingBackColor = Color.Yellow dgdtblStyle.AllowSorting = True dgdtblStyle.RowHeadersVisible = dgdtblStyle.HeaderFont = New System.Drawing.Font("Microsoft Sans Serif", 9.0F, System.Drawing.FontStyle.Bold, GraphicsUnit.Point, 0) dgdtblStyle.GridLineColor = Color.DarkGray dgdtblStyle.PreferredRowHeight = 22 dgdProducts.BackgroundColor = Color.White End If 'Set DataGrid source as the table "Products" dgdProducts.DataSource = tblProducts 'To add the combo box dynamically to the data grid, you have to take the 'Text Box that is present (by default) in the column where u want to add 'this combo box (here it is third column i.e. SupplierID).From the 'tablestyles of the data grid take the grid column styles of the column 'where you want to add the combo box respectively. Dim dgtb As DataGridTextBoxColumn = dgdProducts.TableStyles(0).GridColumnStyles(2) 'Add the combo box to the text box taken in the above step dgtb.TextBox.Controls.Add(cboSupplier) End Sub
Cho chạy chương trình, khi bạn vào cột “SupplierID”, một Combobox sẽ hiện ra với tên các nhà cung cấp như hình dưới đây:Code:Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) … PopulateGrid() End Sub
Figure 1: Product Grid with ComboBox in SupplierID column
Bước 7: Làm cho ComboBox phản ánh dữ liệu trong từng cell
Khi chạy chương trình bạn có thể nhận thấy ngay là mặc dù Combobox có xuất hiện nhưng các Supplier mà nó hiển thị chẳng “ăn nhập” gì với dữ liệu trong cột và khi bạn chọn một nhà cung cấp mới thì mã nhà cung cấp trong cột SupplierID cũng không được cập nhật. Để thực hiện điều này bạn phải thêm vào hai thủ tục:
- (1) Thủ tục làm cho khi ComboBox hiện ra, nó sẽ phản ánh Supplier phù hợp với SupplierID
(2) Thủ tục khi có sự thay đổi khi chọn Supplier mới, mã trong cột SupplierID sẽ được cập nhật.
Bạn có thể làm điều này qua hai event của ComboBox là: VisibleChanged và SelectionChangeCommitted. Bạn thêm vào hai Handler vào ngày dưới phần khởi tạo Combobox trong thủ tục PopulateGrid() như sau:
Và viết các thủ tục tương ứng:Code:With cboSupplier .DropDownStyle = ComboBoxStyle.DropDownList .Dock = DockStyle.Fill .DataSource = tblSuppliers .ValueMember = tblSuppliers.Columns(0).ToString .DisplayMember = tblSuppliers.Columns(1).ToString End With 'Add handlers to ComboBox AddHandler cboSupplier.VisibleChanged, AddressOf cboSupplier_VisibleChanged AddHandler cboSupplier.SelectionChangeCommitted, AddressOf cboSupplier_SelectionChanged
Giờ bạn đã có một Datagrid với ComboBox khá hoàn chỉnh. Tuy nhiên, nó có những hạn chế sau:Code:Private Sub cboSupplier_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs) Dim cbo As ComboBox = sender If cbo.Visible = True Then Dim rownum As Integer = dgdProducts.CurrentRowIndex If rownum < tblProducts.Rows.Count Then cbo.SelectedValue = tblProducts.Rows(rownum).Item(2) Else cbo.SelectedIndex = 0 End If End If End Sub Private Sub cboSupplier_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Dim cbo As ComboBox = sender Dim rownum As Integer = dgdProducts.CurrentRowIndex dgdProducts.Item(rownum, 2) = cbo.SelectedValue End Sub
- Người dùng không thấy được tên các nhà cung cấp (trừ phi nhấp vào cột SupplierID) mà chỉ thấy mã nhà cung cấp – các con số kém trực quan.
- Các cột và Header cố định và phụ thuộc vào cấu trúc của datasource.
Trong phần tiếp theo tôi sẽ trình bày cách mà bạn có thể hiển thị tên các Supplier thay vì các ID và cách nắm toàn quyền việc hiển thị dữ liệu trong Datagrid.Net
Cảm ơn các bạn đã đọc bài viết này.Được sửa bởi danceswithwolves lúc 12:26 ngày 13-01-2003
- (1) Thủ tục làm cho khi ComboBox hiện ra, nó sẽ phản ánh Supplier phù hợp với SupplierID
-
22-01-2003 08:29 #2
Bài khá hay ,nhưng sau không tiếp tục đi chớ ?
-
23-01-2003 14:29 #3
Làm ơn cho hỏi với nếu viết
dgdProducts.DataSource = tblProducts
thì các column trong datagrid có tên là tên các fields trong database như thế không đẹp lắm. Nếu muốn thay đổi thì làm thế nào. Tôi tìm mãi mà không thấy
-
24-01-2003 09:49 #4
Mình sẽ đề cập tới vấn đề này trong Phần II, sorry vì dạo này cuối năm hơi bận nên không tập trung viết dc.
-
25-01-2003 12:00 #5
nhanh len nhe.
-
23-07-2004 18:27 #6
Có huynh nào có bản Licence của "DataGridColumn.DLL( trên www.RustemSoft.com)" không. Nó để chèn Hình, ComboBox, CheckBox, Memo... vào DataGrid.
Nếu có cho đệ xin vơí, đang cần gấp để hoàn thành đồ án, không có chắc tiêu quá.
Trên trang www.RustemSoft.com chỉ có bản demo thôi,sau 1 tháng nó cắt. Lúc đầu đệ không biết nên đã dùng nó khá nhiêù trong Đồ án. Giờ gần xong rồi thì nó không cho dùng nữa.
Nếu không kiếm được bản Licence chắc phải viết lại cái DA qúa.
Cưú đệ với mấy huynh ơi.
Nếu ai có bản Licence, xin mail cho đệ: thaychua31@yahoo.com
Xin hậu tạ.
-
24-07-2004 09:46 #7
Cho mình xin file zip được không? Thanks.
-
24-07-2004 10:07 #8
Bạn lên ngay trang chủ của nó có phần cho bạn Down liền đó.
-
28-07-2004 07:29 #9
Registered User
- Tham gia
- 08-03-2004
- Bài viết
- 16
- Like
- 0
- Thanked 0 Times in 0 Posts
Trang nàoooooooooooooo ???
-
28-07-2004 07:39 #10
chắc chắn sửa được tên field trong dataGrid đó, vọc đi. Tui làm rồi, mò 2 tiếng mới ra được.


Quote
Bookmarks