Trang 1 / 3 123 LastLast
Hiển thị kết quả từ 1 đến 10 / 21
  1. #1
    Tham gia
    06-01-2003
    Location
    TP.HCM
    Bài viết
    56
    Like
    0
    Thanked 3 Times in 3 Posts

    Sử Dụng DataGrid.Net - Phần II

    Sử Dụng DataGrid.Net Phần II

    Note: Bạn có thể download bài viết dạng .doc và sourcecode gởi kèm

    3. Nắm Toàn Quyền Điều Khiển Giao Diện DataGrid.Net

    Cho đến giờ, bạn đã có một Datagrid có Combobox ở cột SupplierID nhưng bạn không thể hiển thị tên của các Suppliers thay vì các ID, ngoài ra cấu trúc của các cột phụ thuộc vào cấu trúc của dataset. Bạn sẽ phải làm gì nếu muốn thay đổi thứ tự các cột (VD: đưa cột “Discontinued” lên đầu tiên?)

    Bạn hãy xem giao diện được cải thiện như dưới đây:
    (To see picture, download attached file)
    So với phiên bản trước, phiên bản này có những cải tiến sau:
    • Các cột có thể di chuyển tới vị trí bất kỳ, không phụ thuộc vào cấu trúc của datasource (datatable) nữa. VD: Cột “Discontinued” được di chuyển lên vị trí đầu tiên.
    • Các header cột thể hiện tên tùy ý. VD: “Unit Price” thay vì “UnitPrice”.
    • Cột “Supplier” với tên đầy đủ của các nhà cung cấp thay cho cột “SupplierID” với những mã số kém trực quan.


    Để thực hiện được việc này, trước hết chúng ta hãy xem qua một vài kỹ thuật có thể áp dụng được trong Datagrid.Net:

    [list=1][*] Datagrid.Net có hai dạng cột (column styles) có sẵn là Textbox (DataGridTextBoxColumn) và Checkbox (DataGridBoolColumn), bạn có thể tạo/thêm các cột này vào lúc thiết kế hay runtime. Nếu không, khi bạn gắn Datagrid vào CSDL, nó sẽ tự tạo ra các cột tương ứng với các cột dữ liệu theo cấu trúc của Dataset, nếu các cột có dữ liệu dạng False/True thì sẽ được hiển thị trong DataGridBoolColumn còn các dạng khác sẽ bị biến thành dạng text hết và hiển thị trong DataGridTextBoxColumn. Ngoài ra, bạn có thể tự tạo ra các column style khác (custom) và gắn vào datagrid (tôi sẽ đề cập tới vấn đề này trong một bài khác).[*] Các cột của Datagrid.Net có thể gắn kết với một cột dữ liệu (bound) hay hoàn toàn độc lập với CSDL. Để gắn chính xác một cột của Datagrid.Net với một cột trong datatable, ta sẽ sử dụng kỹ thuật Mapping Name - nghĩa là gán tên cột dữ liệu vào cột của Datagrid.
    Ngoài ra ta cũng có thể thêm các cột dữ liệu unbound vào Datatable, các cột này sẽ không dùng để update CSDL chính mà chỉ dùng để thể hiện các dữ liệu theo ý của bạn.[*] Hình thức thể hiện (màu sắc, font chữ...) của Datagrid.Net có thể thay đổi thông qua các DataGridTableStyle gắn kết với nó. Xin các bạn xem lại đoạn code tạo và sử dụng TableStyle trong Phần I (ở thủ tục PopulateGrid()):[/list=1]

    Code:
    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
    Bây giờ chúng ta hãy bắt tay vào tạo dựng Datagrid của mình.

    Bước 1: Thêm cột unbound “Supplier” vào datatable tblProducts

    Trong thủ tục PopulateGrid(), sau phần tạo Combobox bạn thêm đoạn mã sau:

    Code:
    	'Add an unbound column that comtain Combobox to main datatable
            Dim dcolCombo As DataColumn
    
            dcolCombo = New DataColumn("Supplier")
            With dcolCombo
                .DataType = System.Type.GetType("System.String")
                .DefaultValue = ""
            End With
            tblProducts.Columns.Add(dcolCombo)
    Lúc này cột dữ liệu mới thêm vào hoàn toàn trống rổng, bạn phải fill dữ liệu – tên các supplier – vào bằng cách gọi thủ tục:
    Code:
    FillUnboundColumn()
    và viết code để fill tên Supplier tương ứng với SupplierID trong bảng “Products”. Hai thủ tục/hàm sau sẽ giúp bạn thực hiiện điều này:
    Code:
    	Private Sub FillUnboundColumn()
            Dim i As Integer
            Dim dRow As DataRow
    
    'Go to each row of unbound column "Supplier" and fill with meaningful data
            For i = 0 To tblProducts.Rows.Count - 1
                dRow = tblProducts.Rows(i)
                'Fill "Supplier" column with supplier name inaccordance with SupplierID
                dRow("Supplier") = FindSupplierName(dRow("SupplierID"))
            Next
    
    'Set default value for "SupplierID" column, so that when you add new row
            'the Datagrid will behave correctly
            tblProducts.Columns("SupplierID").DefaultValue = 1
        End Sub
    
        Private Function FindSupplierName(ByVal ID As Integer) As String
            Dim i As Integer
            Dim dRow As DataRow
            For i = 0 To tblSuppliers.Rows.Count - 1
                dRow = tblSuppliers.Rows(i)
                If dRow(0) = ID Then
                    Return dRow(1).ToString
                End If
            Next
        End Function
    Bước 2: Tạo mới các column trong Datagrid

    Như vậy hiện giờ tblProducts có 7 cột dữ liệu, để thể hiện chúng theo ý mình, bạn cần tạo ra 7 cột tương ứng trong Datagrid. Nếu bạn muốn cột đó có chứa CheckBox thì bạn tạo loại cột DataGridBoolColumn, còn không bạn tạo dạng DataGridTextBoxColumn. Ở đây ta muốn đưa cột “Discontinued” là dạng False/True lên đầu tiên để tiện theo dõi những hàng nào không còn đặt mua nữa. Ta thêm đoạn code sau vào ngay sau phần tạo và format DataGridTableStyle vừa trình bày ở trên:

    Code:
    Private Sub PopulateGrid()
    …
            If (Not dgdProducts.TableStyles.Contains("Products")) Then
    …
    
                Dim i As Integer
                For i = 0 To 6
                    If i <> 0 Then
                        Dim gridcol As New DataGridTextBoxColumn()
                        dgdtblStyle.GridColumnStyles.Add(gridcol)
                    Else
                        Dim gridcol As New DataGridBoolColumn()
                        dgdtblStyle.GridColumnStyles.Add(gridcol)
                    End If
                Next
    End If
        End Sub
    Bước 3: Gán các cột trong datatable tblProducts vào các cột của Datagrid.Net

    Sau khi tạo ra các cột, việc tiếp theo là chúng ta phải làm cho Datagrid hiểu cột nào sẽ thể hiện dữ liệu của cột nào trong datatable và định ra header text, chiều rộng của các cột. Thêm vào phần code như dưới đây:
    Code:
    Private Sub PopulateGrid()
    ...
            If (Not dgdProducts.TableStyles.Contains("Products")) Then
    ...
              ...
    'Mapping datagrid columns to column names of “tblProducts” and 
    'format header text and column width.
                Dim colStyle As GridColumnStylesCollection
    
                colStyle = dgdProducts.TableStyles(0).GridColumnStyles
    
                colStyle(0).MappingName = "Discontinued"
                colStyle(0).HeaderText = "Discontinued"
                '
                colStyle(1).MappingName = "ProductID"
                colStyle(1).HeaderText = "Product ID"
                '
                colStyle(2).MappingName = "ProductName"
                colStyle(2).HeaderText = "Product Name"
                colStyle(2).Width = 150
                '
                colStyle(3).MappingName = "Supplier"
                colStyle(3).HeaderText = "Supplier"
                colStyle(3).Width = "150"
                '
                colStyle(4).MappingName = "QuantityPerUnit"
                colStyle(4).HeaderText = "Quantity"
                '
                colStyle(5).MappingName = "UnitPrice"
                colStyle(5).HeaderText = "Unit Price"
                '
                colStyle(6).MappingName = "SupplierID"
                colStyle(6).Width = 0
            End If
            
            '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. Supplier).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(3)
    
            'Add the combo box to the text box taken in the above step 
            dgtb.TextBox.Controls.Add(cboSupplier)
    
    'Set DataGrid source as the table "Products"
            dgdProducts.DataSource = tblProducts
        End Sub
    =>Ở đây bạn lưu ý hai điểm sau:
    • Cột SupplierID được đưa ra sau cùng và có chiều rộng là 0, nghĩa là người sử dụng sẽ không thấy được cột này.
    • Bạn phải đặt DataSource cho datagrid sau khi đã mapping name nếu không khi chạy chương trình sẽ báo lỗi là không thể Mapping name được vì tên này đã có rồi.

    Bước 4: Bỏ qua hoàn toàn cột SupplierID

    Mặc dù ở bước trên, bạn đã cho cột SupplierID ẩn dấu nhưng nó chưa thực sự “biến mất” hoàn toàn. Nếu bạn dùng tab di chuyển giữa các ô của Datagrid bạn sẽ nhận thấy nó vẫn dừng lại ở cột cuối cùng dù không nhìn thấy. Để bỏ qua cột này, chúng ta phải thêm một thủ tục để khi một cell trong cột này nhận focus nó sẽ chuyển ngay focus về cell của cột đầu tiên, hàng tiếp theo.

    Muốn vậy, bạn thêm một handler điều khiển việc nhận focus của textbox trong cột SupplierID (cột 6). Gõ vào đoạn mã này vào cuối thủ tục PopulateGrid():
    Code:
    'Add handlers to control grid navigation so that all hided columns will be passed by
            	dgtb = dgdProducts.TableStyles(0).GridColumnStyles(6)
            	AddHandler dgtb.TextBox.GotFocus, AddressOf Col6_GotFocus
    Và viết thủ tục Col6_GotFocus:
    Code:
    Private Sub Col6_GotFocus(ByVal sender As Object, ByVal e As EventArgs)
            Dim colnum As Integer = dgdProducts.CurrentCell.ColumnNumber
            If colnum <> 6 Then Exit Sub
    
            'Set focus to the cell of first column, next row
            Dim cell As New DataGridCell(dgdProducts.CurrentRowIndex + 1, 0)
            dgdProducts.CurrentCell = cell
    End Sub
    Bước 5: Làm cho ComboBox cập nhật đúng dữ liệu

    Khi bạn chọn một item mới trong ComboBox ở cột “Supplier”, ComboBox sẽ phải cập nhật phần Text vào cột “Supplier” (cột 3) và phần Value vào cột “SupplierID” (cột 6). Bạn sửa lại hai thủ tục cboSupplier_VisibleChanged và cboSupplier_SelectionChanged như sau:
    Code:
    Private Sub cboSupplier_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim cbo As ComboBox = sender
            Dim rownum As Integer = dgdProducts.CurrentRowIndex
    
            Dim intSupplierID As Integer = 0
            Try
                intSupplierID = dgdProducts.Item(rownum, 6).ToString()
            Catch Err As Exception
                'Do nothing here
            Finally
                cbo.SelectedValue = intSupplierID
            End Try
        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
    
            'Set value to column "SupplierID"
            dgdProducts.Item(rownum, 6) = cbo.SelectedValue
            'Set value to unbound column "Supplier"
            dgdProducts.Item(rownum, 3) = cbo.Text
        End Sub
    Bước 6: Cập nhật CSDL gốc

    Đến đây bạn đã có một Datagrid.Net với giao diện hoàn chỉnh. Nhưng như bạn đã biết, ADO.Net là dạng disconnected nên những gì bạn sửa đổi ở trên giao diện chỉ có tác dụng khi bạn update CSDL gốc bằng một thủ tục tường minh. Thiết nghĩ các bạn quá rành việc này rồi (còn nếu chưa xin các bạn tham khảo các cuốn sách về VB.Net). Trong phần tutorial này tôi xin nhường cho các bạn viết thủ tục update này vì không muốn là hỏng CSDL Northwind.mdb.

    Cảm ơn các bạn đã đọc.
    Attached Files
    Quote Quote

  2. Thành viên Like bài viết này:


  3. #2
    Tham gia
    06-02-2003
    Location
    vùng sâu vùng xa
    Bài viết
    549
    Like
    1
    Thanked 6 Times in 6 Posts
    Bài viết của bạn khá hay đó !

    Thông thường, với những chương trình đòi hỏi giao diện phức tạp thì DataGrid của MS không thể đáp ứng được. Theo tôi, chúng ta có thể sử dụng những DataGrid có độ chuyện nghiệp cao hơn như:
    - NetAdvantage
    - ComponentOne
    - Janus
    - GidX
    - . . .
    Các thành phần này không có free nhưng có rất nhiếu đã được ***** và post lên Internet, việc tìm và download không có khó khăn gì lắm !

  4. #3
    Tham gia
    23-11-2002
    Bài viết
    43
    Like
    0
    Thanked 0 Times in 0 Posts
    Dưới dạng .dll hay là source code dzậy huynh?

  5. #4
    Tham gia
    06-02-2003
    Location
    vùng sâu vùng xa
    Bài viết
    549
    Like
    1
    Thanked 6 Times in 6 Posts
    DLL. Chỉ 1 số có source code thôi, viết bằng C++ hoặc C#. Nhưng mà làm sao đọc nổi mà đọc. Học cách sử dụng thôi là ngất ngư rồi !

  6. #5
    Tham gia
    10-01-2003
    Bài viết
    1
    Like
    0
    Thanked 0 Times in 0 Posts
    thế bạn có thể cho biết địa chỉ download bản ***** của các tool đó không. thanx.

  7. #6
    Tham gia
    20-01-2003
    Bài viết
    150
    Like
    0
    Thanked 3 Times in 2 Posts
    Cho tôi hỏi thêm và DataGrid với
    - làm thế nào kiểm soát hay ngăn chặn việc thêm hay xoá 1 dòng trong grid mà trong khi vẫn có thể sửa được các ô hiện có ( có nghĩa là thuộc tính ReadOnly vẫn phải đặt là False)
    - khi thêm 1 ô CheckBox vào 1 cell, nó sẽ có 3 trạng thái Check, Uncheck và Gray. Làm thế nào để bỏ cái Gray đi, chỉ để lại 2 trạng thái Check, Uncheck thôi.

  8. #7
    hyvongmauxanh Guest
    Chúng mày sao ngu như bò thế hả. Bộ điên hết rồi à. Cái thằng ViKhoa gì đó, kinh doanh mắc như chó. Chỉ lợi dụng các bạn thôi, công nhận làm chỗ sân chơi cũng tốt, nhưng lừa bịp lợi dụng bạn bè hơi bị nhiều. Có ngày tao sẽ kill cái trang web này. Còn mấy thằng bên box ***curity gì đó, ngu cả một lũ, để trang web bị hack hoài. Đúng là một lũ thùng rỗng kêu to. Một lũ mất dạy. Chúc tụi bay vui vẻ nhé.

  9. #8
    Tham gia
    16-07-2002
    Location
    none
    Bài viết
    29
    Like
    0
    Thanked 0 Times in 0 Posts
    Hi ham_tim_hieu!
    Bạn không cần phải ReadOnly, chỉ cần khóa việc thêm và xóa trong DataGrid thôi.

    CurrencyManager cm = (CurrencyManager)this.BindingContext[dataGrid1.DataSource,dataGrid1.DataMember];
    ((DataView)cm.List).AllowNew=false; //không được thêm,
    ((DataView)cm.List).AllowDelete=false;// không được xóa

  10. #9
    Tham gia
    03-02-2003
    Bài viết
    302
    Like
    0
    Thanked 2 Times in 1 Post
    Anh lazy-programmer oi cho em xin phần "Sử Dụng DataGrid.Net Phần I" di, hiện giờ em chi co "Sử Dụng DataGrid.Net Phần II" thoi, mail cua em la hoangminh0317@yahoo.com cam on anh nhiều!

  11. #10
    Tham gia
    06-01-2003
    Location
    TP.HCM
    Bài viết
    56
    Like
    0
    Thanked 3 Times in 3 Posts
    Bạn cho mình d/c e-mail, mình sẽ gởi bạn toàn bộ bài viết và sourcecode.

Trang 1 / 3 123 LastLast

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •