要想在DataGrid中運用ComboBox,DateTimePicker,我可以對System.Windows.Forms.DataGridColumnStyle進行重寫來做到....
(C#部分請點擊)
一、將ComboBox綁定與DataGridColumnStyle ,然後對DataGridColumnStyle進行重寫...
代碼與下:
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class X_DataGridComboBoxStyle
Inherits System.Windows.Forms.DataGridColumnStyle
'''定義一ComBox,然後將Combox 與DataGridColumnStyle綁定進行重寫...
Private X_ComboBox As ComboBox = New ComboBox
Private IsEditing As Boolean
Sub New()
Me.X_ComboBox.Visible = False
End Sub
Protected Overrides Sub Abort(ByVal rowNum As Integer)
Me.IsEditing = False
Me.Invalidate()
End Sub
Protected Overrides Function Commit(ByVal dataSource As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer) As Boolean
Me.X_ComboBox.Bounds = Rectangle.Empty
AddHandler X_ComboBox.Click, AddressOf ComboBoxValueChanged '''激活事件
If Not Me.IsEditing Then
Return True
End If
IsEditing = False
Try
Dim value As String
value = X_ComboBox.Text
SetColumnValueAtRow(dataSource, rowNum, value)
Catch ex As Exception
Abort(rowNum)
Return False
End Try
invalidate()
Return True
End Function
Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
Dim value As String
value = Convert.ToString(GetColumnValueAtRow(source, rowNum))
If cellIsVisible Then
Me.X_ComboBox.Bounds = New Rectangle(bounds.X + 2, bounds.Y + 2, bounds.Width - 4, bounds.Height - 4)
Me.X_ComboBox.Text = value
Me.X_ComboBox.Visible = True
AddHandler X_ComboBox.Click, AddressOf ComboBoxValueChanged '''激活事件
Else
Me.X_ComboBox.Text = value
Me.X_ComboBox.Visible = False
End If
If Me.X_ComboBox.Visible Then
DataGridTableStyle.DataGrid.Invalidate(bounds)
End If
End Sub
Protected Overrides Function GetMinimumHeight() As Integer
Return 24
End Function
Protected Overrides Function GetPreferredHeight(ByVal g As System.Drawing.Graphics, ByVal value As Object) As Integer
Return 24
End Function
Protected Overrides Function GetPreferredSize(ByVal g As System.Drawing.Graphics, ByVal value As Object) As System.Drawing.Size
Return New Size(100, 24)
End Function
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer)
Paint(g, bounds, source, rowNum, False)
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal alignToRight As Boolean)
Paint(g, bounds, source, rowNum, Brushes.Red, Brushes.Blue, alignToRight)
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal foreBrush As Brush, ByVal backBrush As Brush, ByVal alignToRight As Boolean)
Dim dates As String = Convert.ToString(GetColumnValueAtRow(source, rowNum))
Dim rect As System.Drawing.Rectangle = bounds
g.FillRectangle(Brushes.White, rect)
rect.Offset(0, 2)
rect.Height -= 2
g.DrawString(dates, Me.DataGridTableStyle.DataGrid.Font, Brushes.Black, rect.X, rect.Y)
End Sub
Protected Overloads Overrides Sub SetDataGridInColumn(ByVal value As DataGrid)
MyBase.SetDataGridInColumn(value)
If Not Me.X_ComboBox.Parent Is Nothing Then
Me.X_ComboBox.Visible = False
Me.X_ComboBox.Controls.Remove(Me.X_ComboBox)
End If
If Not value Is Nothing Then
value.Controls.Add(Me.X_ComboBox)
End If
End Sub
'''定義一個ComboxChange 事件
Private Sub ComboBoxValueChanged(ByVal sender As Object, ByVal e As EventArgs)
Me.IsEditing = True
MyBase.ColumnStartedEditing(X_ComboBox)
End Sub
'''定義一個添加Combox的Items添加屬性
Public Sub AddItem(ByVal StrItemName As String)
Me.X_ComboBox.Items.Add(StrItemName)
End Sub
End Class
二、將DateTimePicker綁定與DataGridColumnStyle ,然後對DataGridColumnStyle進行重寫...
代碼與下:
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class X_DataGridDateTimePickerColumnStyle
Inherits System.Windows.Forms.DataGridColumnStyle
Private IsEditing As Boolean
'''定義一個 DateTimePicker
Private X_DateTimePicker As System.Windows.Forms.DateTimePicker = New DateTimePicker
Sub New()
Me.X_DateTimePicker.Visible = False
End Sub
Protected Overrides Sub Abort(ByVal rowNum As Integer)
Me.IsEditing = False
Me.Invalidate()
End Sub
Protected Overrides Function Commit(ByVal dataSource As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer) As Boolean
Me.X_DateTimePicker.Bounds = Rectangle.Empty
AddHandler X_DateTimePicker.ValueChanged, AddressOf Me.DatePickerVilueChange '''激活事件
If Not Me.IsEditing Then
Return True
End If
Me.IsEditing = False
Try
Dim value As String = Me.X_DateTimePicker.Value
SetColumnValueAtRow(dataSource, rowNum, value)
Catch ex As Exception
Me.Abort(rowNum)
Return False
End Try
Me.Invalidate()
Return True
End Function
Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
Dim value As String
value = Convert.ToDateTime(GetColumnValueAtRow(source, rowNum))
If cellIsVisible Then
Me.X_DateTimePicker.Bounds = New Rectangle(bounds.X + 2, bounds.Y + 2, bounds.Width - 4, bounds.Height - 4)
Me.X_DateTimePicker.Value = value
Me.X_DateTimePicker.Visible = True
AddHandler X_DateTimePicker.ValueChanged, AddressOf Me.DatePickerVilueChange '''激活事件
Else
Me.X_DateTimePicker.Value = value
Me.X_DateTimePicker.Visible = False
End If
If Me.X_DateTimePicker.Visible Then
DataGridTableStyle.DataGrid.Invalidate(bounds)
End If
End Sub
Protected Overrides Function GetMinimumHeight() As Integer
Return 24
End Function
Protected Overrides Function GetPreferredHeight(ByVal g As System.Drawing.Graphics, ByVal value As Object) As Integer
Return 24
End Function
Protected Overrides Function GetPreferredSize(ByVal g As System.Drawing.Graphics, ByVal value As Object) As System.Drawing.Size
Return New Size(100, 24)
End Function
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer)
Paint(g, bounds, source, rowNum, False)
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal alignToRight As Boolean)
Paint(g, bounds, source, rowNum, Brushes.Red, Brushes.Blue, alignToRight)
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal forebrush As Brush, ByVal bcakbrush As Brush, ByVal alignToRight As Boolean)
Dim dates As String = Convert.ToDateTime(GetColumnValueAtRow(source, rowNum))
Dim rect As System.Drawing.Rectangle = bounds
g.FillRectangle(Brushes.White, rect)
rect.Offset(0, 2)
rect.Height -= 2
g.DrawString(dates, Me.DataGridTableStyle.DataGrid.Font, Brushes.Black, rect.X, rect.Y)
End Sub
'''定義一個DatePickerVilueChange 事件,供操作時用
Private Sub DatePickerVilueChange(ByVal sender As Object, ByVal e As EventArgs)
Me.IsEditing = True
MyBase.ColumnStartedEditing(X_DateTimePicker)
End Sub
Protected Overloads Overrides Sub SetDataGridInColumn(ByVal value As DataGrid)
MyBase.SetDataGridInColumn(value)
If Not Me.X_DateTimePicker.Parent Is Nothing Then
Me.X_DateTimePicker.Visible = False
Me.X_DateTimePicker.Controls.Remove(Me.X_DateTimePicker)
End If
If Not value Is Nothing Then
value.Controls.Add(Me.X_DateTimePicker)
End If
End Sub
End Class
● 到此,兩個重寫的UIControl都已完成,現在新建一個Form,在Form中放置一個DataGird,我們將在DataGrid中同時實現運用ComboBox,DateTimePicker,CheckBox…..
代碼部分:
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.DataGrid1 = New System.Windows.Forms.DataGrid
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'DataGrid1
'
Me.DataGrid1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
Me.DataGrid1.DataMember = ""
Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
Me.DataGrid1.Location = New System.Drawing.Point(4, 4)
Me.DataGrid1.Name = "DataGrid1"
Me.DataGrid1.Size = New System.Drawing.Size(634, 246)
Me.DataGrid1.TabIndex = 0
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(642, 253)
Me.Controls.Add(Me.DataGrid1)
Me.Name = "Form1"
Me.Text = "Form1"
CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
#End Region
Private idtb_temp As New DataTable
Private Sub AddDate()
Dim idrw_row As DataRow
idrw_row = idtb_temp.NewRow
idrw_row.Item("name") = "xx0"
idrw_row.Item("state") = "111"
idrw_row.Item("dates") = System.DateTime.Now.ToShortDateString
idrw_row.Item("chioce") = True
idtb_temp.Rows.Add(idrw_row)
idrw_row = idtb_temp.NewRow
idrw_row.Item("name") = "xx0"
idrw_row.Item("state") = "222"
idrw_row.Item("dates") = System.DateTime.Now.ToShortDateString
idrw_row.Item("chioce") = False
idtb_temp.Rows.Add(idrw_row)
End Sub
Private Sub datastyle()
Dim myGridStyle As DataGridTableStyle = New DataGridTableStyle
myGridStyle.MappingName = "NameTable"
Dim nameColumnStyle As DataGridTextBoxColumn = New DataGridTextBoxColumn
nameColumnStyle.MappingName = "name"
nameColumnStyle.Width = 100
nameColumnStyle.HeaderText = "名字"
myGridStyle.GridColumnStyles.Add(nameColumnStyle)
Dim comboxColumnStyle As X_DataGridComboBoxStyle = New X_DataGridComboBoxStyle
comboxColumnStyle.MappingName = "state"
comboxColumnStyle.HeaderText = "狀態"
comboxColumnStyle.Width = 100
comboxColumnStyle.AddItem("111")
comboxColumnStyle.AddItem("222")
myGridStyle.GridColumnStyles.Add(comboxColumnStyle)
Dim DatePickColumnStyle As X_DataGridDateTimePickerColumnStyle = New X_DataGridDateTimePickerColumnStyle
DatePickColumnStyle.MappingName = "dates"
DatePickColumnStyle.HeaderText = "日期"
DatePickColumnStyle.Width = "100"
myGridStyle.GridColumnStyles.Add(DatePickColumnStyle)
Dim boolColumnStyle As DataGridBoolColumn = New DataGridBoolColumn
boolColumnStyle.MappingName = "chioce"
boolColumnStyle.HeaderText = "選擇"
boolColumnStyle.Width = 100
boolColumnStyle.AllowNull = False '''
boolColumnStyle.TrueValue = True ''' 解決 checkbox 的三態性問題
boolColumnStyle.FalseValue = False '''
boolColumnStyle.ReadOnly = False '''
myGridStyle.GridColumnStyles.Add(boolColumnStyle)
Me.DataGrid1.TableStyles.Add(myGridStyle)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
idtb_temp = New DataTable("NameTable")
idtb_temp.Columns.Add(New DataColumn("name"))
idtb_temp.Columns.Add(New DataColumn("state"))
Dim dateColumns As DataColumn
dateColumns = New DataColumn("dates", Type.GetType("System.DateTime"))
idtb_temp.Columns.Add(dateColumns)
idtb_temp.Columns.Add(New DataColumn("chioce", Type.GetType("System.Boolean")))
Me.DataGrid1.DataSource = idtb_temp
datastyle()
AddDate()
End Sub
End Class
運行效果圖(一):Combox In DataGrid
運行效果圖(二): DateTimePicker In DataGrid