dongxf

 

How To Extend the Windows Form DataGridTextBoxColumn Control to Custom-Format Data

How To Extend the Windows Form DataGridTextBoxColumn Control to Custom-Format Data

Article ID : 318581
Last Review : July 15, 2004
Revision : 3.1
This article was previously published under Q318581

SUMMARY

This step-by-step article describes how to extend the Windows Form DataGridTextBoxColumn control so that you can custom-format your data for display and editing in a Windows Form DataGrid.

The program demonstrates how to add "CR" to negative numbers and how to parse numbers with the "CR" suffix as being negative. You can extend this technique to any data type, including enumerations and user-defined types. To display data, you override the GetColumnValueAtRow method. To parse data, you override the Commit method.

Sample Program

1. Start Microsoft Visual Studio .NET, and then create a new Visual Basic Windows Form application.
2. Add a DataGrid control to the form.
3. Type or paste the following sample code into the form's code window. The code contains the CRTextBoxColumn class that extends the DataGridTextBoxColumn class. It also adds a Form.Load event handler to generate sample data and initialize the DataGrid to use the CRTextBoxColumn class:
Private ds As New DataSet()
            Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '
            ' Generate sample data
            '
            ' Two columns:
            '    Decimal - uses CRTextBoxColumn for column style.
            '    Integer - uses standard DataGridTextBoxColumn for column style.
            '
            Dim dt As New DataTable()
            dt.TableName = "TestTable"
            dt.Columns.Add("Amount", GetType(Decimal))
            dt.Columns.Add("ColB", GetType(Integer))
            ds.Tables.Add(dt)
            dt.Rows.Add(New Object() {2, 4})
            dt.Rows.Add(New Object() {-3.45, 5})
            dt.Rows.Add(New Object() {4.25, 6})
            dt.Rows.Add(New Object() {-1.33, 7})
            '
            ' Create DataGridTableStyle and DataGridColumnStyle objects
            ' and add them the the DataGrid.
            '
            Dim ts As New DataGridTableStyle(), cs As DataGridColumnStyle
            ' Add the custom column style.
            cs = New CRTextBoxColumn()
            cs.Width = 120
            cs.MappingName = "Amount"        ' Map to decimal column.
            cs.HeaderText = "Charge/Payment"
            ts.GridColumnStyles.Add(cs)
            ' Add the standard column style.
            cs = New DataGridTextBoxColumn()
            cs.Width = 100
            cs.MappingName = "ColB"          ' Map to integer column.
            cs.HeaderText = "Integer Col"
            ts.GridColumnStyles.Add(cs)
            ts.MappingName = "TestTable"     ' Map table style to TestTable.
            DataGrid1.TableStyles.Add(ts)
            DataGrid1.DataSource = ds
            DataGrid1.DataMember = "TestTable"
            End Sub
            Class CRTextBoxColumn
            Inherits DataGridTextBoxColumn
            Protected Overrides Function GetColumnValueAtRow(ByVal cm As CurrencyManager, ByVal RowNum As Integer) As Object
            '
            ' Get data from the underlying record and format for display.
            '
            Dim oVal As Object = MyBase.GetColumnValueAtRow(cm, RowNum)
            If oVal.GetType Is GetType(DBNull) Then
            Return ""                         ' String to display for DBNull.
            Else
            ' CDec on next statement will throw an exception if this
            ' column style is bound to a column containing non-numeric data.
            Dim Temp As Decimal = CDec(oVal)
            If Temp >= 0 Then
            Return Temp.ToString("0.00")             ' positive number
            Else
            Return (-Temp).ToString("0.00") & "CR"   ' negative number
            End If
            End If
            End Function
            Protected Overrides Function Commit(ByVal cm As CurrencyManager, ByVal RowNum As Integer) As Boolean
            '
            ' Parse the data and write to underlying record.
            '
            Me.HideEditBox()   ' return focus to the DataGrid control
            Dim box As DataGridTextBox = CType(Me.TextBox, DataGridTextBox), Value As Decimal
            ' Do not write data if not editing.
            If box.IsInEditOrNavigateMode Then Return True
            If TextBox.Text = "" Then   ' in this example, "" maps to DBNull
            SetColumnValueAtRow(cm, RowNum, DBNull.Value)
            Else
            ' Parse the data.
            Try
            If TextBox.Text.ToUpper.EndsWith("CR") Then
            Value = -Decimal.Parse(TextBox.Text.Substring(0, TextBox.Text.Length - 2))
            Else
            Value = Decimal.Parse(TextBox.Text)
            End If
            Catch
            Return False    ' Exit on error and display old "good" value.
            End Try
            SetColumnValueAtRow(cm, RowNum, Value)   ' Write new value.
            End If
            Me.EndEdit()   ' Let the DataGrid know that processing is completed.
            Return True    ' success
            End Function
            End Class
            
4. Run the application. The DataGrid contains two columns, similar to this:
Charge/Payment   Integer Col
            ----------------------------
            2.00                       4
            3.45CR                     5
            4.25                       6
            1.33CR                     7
            
5. Edit the data. Add, delete, and modify rows. If you type a negative value in the first column (for example, -5.43), it appears without the negate sign (-). Instead, "CR" is added (for example, 5.43CR). You can also type numbers with the "CR" suffix directly into the DataGrid.

Pitfalls

This section lists some common problems that you may experience when you implement the sample code that is listed in this article.
Do not bind the column style that is included with this article to a column that does not contain numeric data. If you do, you receive an exception when the data is about to be displayed.
If you bind to a text column that contains numeric data, you must make sure that the locale of the data matches that of the computer. If you do not, problems in parsing the existing values may occur. You may receive incorrect results or an exception. New values may be written with different formatting than is supported by other programs that may share the data.
The column does not appear if you do not set the Width property. If you do not set the property, the column uses 0 (hidden).
The data does not appear if you do not set MappingName for both the DataGridTableStyle and DataGridColumnStyle objects, and assign them to their respective collections.
The column heading is blank if you do not set the HeaderText property.

APPLIES TO
Microsoft Visual Basic .NET 2002 Standard Edition
Microsoft Visual Basic .NET 2003 Standard Edition
Microsoft .NET Framework 1.1 Service Pack 1
Microsoft ADO.NET 1.1
Microsoft .NET Framework Software Development Kit 1.0
Microsoft .NET Framework Software Development Kit 1.0 Service Pack 2

posted on 2006-08-07 10:59  dongxf  阅读(483)  评论(0)    收藏  举报

导航