『转MSDN』如何:在 Windows 窗体 DataGridView 单元格中承载日历控件

来源:互联网 发布:掌阅ireader刷阅饼软件 编辑:程序博客网 时间:2024/05/18 03:17
如何:在 Windows 窗体 DataGridView 单元格中承载控件

DataGridView 控件提供了多种列类型,使得用户可以通过多种方式输入和编辑值。但是,如果这些列类型无法满足数据输入要求,您也可以使用承载所选控件的单元格创建自己的列类型。要做到这一点,必须定义派生自 DataGridViewColumn 和 DataGridViewCell 的类。您还必须定义派生自 Control 并实现 IDataGridViewEditingControl 接口的类。

下面的代码示例演示如何创建日历列。此列的单元格在普通的文本框单元格中显示日期,但当用户编辑单元格时,就会出现 DateTimePicker 控件。为了避免必须再次实现文本框显示功能,CalendarCell 类从 DataGridViewTextBoxCell 类派生,而不是直接从 DataGridViewCell 类继承。

说明:

当从 DataGridViewCell 或 DataGridViewColumn 派生并向派生类添加新属性时,请确保重写 Clone 方法以便在克隆操作期间复制新属性。还应调用基类的 Clone 方法,以便将基类的属性复制到新的单元格或列中。

Visual Basic
复制代码
Imports SystemImports System.Windows.FormsPublic Class CalendarColumn    Inherits DataGridViewColumn    Public Sub New()        MyBase.New(New CalendarCell())    End Sub    Public Overrides Property CellTemplate() As DataGridViewCell        Get            Return MyBase.CellTemplate        End Get        Set(ByVal value As DataGridViewCell)            ' Ensure that the cell used for the template is a CalendarCell.            If (value IsNot Nothing) AndAlso _                Not value.GetType().IsAssignableFrom(GetType(CalendarCell)) _                Then                Throw New InvalidCastException("Must be a CalendarCell")            End If            MyBase.CellTemplate = value        End Set    End PropertyEnd ClassPublic Class CalendarCell    Inherits DataGridViewTextBoxCell    Public Sub New()        ' Use the short date format.        Me.Style.Format = "d"    End Sub    Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, _        ByVal initialFormattedValue As Object, _        ByVal dataGridViewCellStyle As DataGridViewCellStyle)        ' Set the value of the editing control to the current cell value.        MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, _            dataGridViewCellStyle)        Dim ctl As CalendarEditingControl = _            CType(DataGridView.EditingControl, CalendarEditingControl)        ctl.Value = CType(Me.Value, DateTime)    End Sub    Public Overrides ReadOnly Property EditType() As Type        Get            ' Return the type of the editing contol that CalendarCell uses.            Return GetType(CalendarEditingControl)        End Get    End Property    Public Overrides ReadOnly Property ValueType() As Type        Get            ' Return the type of the value that CalendarCell contains.            Return GetType(DateTime)        End Get    End Property    Public Overrides ReadOnly Property DefaultNewRowValue() As Object        Get            ' Use the current date and time as the default value.            Return DateTime.Now        End Get    End PropertyEnd ClassClass CalendarEditingControl    Inherits DateTimePicker    Implements IDataGridViewEditingControl    Private dataGridViewControl As DataGridView    Private valueIsChanged As Boolean = False    Private rowIndexNum As Integer    Public Sub New()        Me.Format = DateTimePickerFormat.Short    End Sub    Public Property EditingControlFormattedValue() As Object _        Implements IDataGridViewEditingControl.EditingControlFormattedValue        Get            Return Me.Value.ToShortDateString()        End Get        Set(ByVal value As Object)            If TypeOf value Is String Then                Me.Value = DateTime.Parse(CStr(value))            End If        End Set    End Property    Public Function GetEditingControlFormattedValue(ByVal context _        As DataGridViewDataErrorContexts) As Object _        Implements IDataGridViewEditingControl.GetEditingControlFormattedValue        Return Me.Value.ToShortDateString()    End Function    Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As _        DataGridViewCellStyle) _        Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl        Me.Font = dataGridViewCellStyle.Font        Me.CalendarForeColor = dataGridViewCellStyle.ForeColor        Me.CalendarMonthBackground = dataGridViewCellStyle.BackColor    End Sub    Public Property EditingControlRowIndex() As Integer _        Implements IDataGridViewEditingControl.EditingControlRowIndex        Get            Return rowIndexNum        End Get        Set(ByVal value As Integer)            rowIndexNum = value        End Set    End Property    Public Function EditingControlWantsInputKey(ByVal key As Keys, _        ByVal dataGridViewWantsInputKey As Boolean) As Boolean _        Implements IDataGridViewEditingControl.EditingControlWantsInputKey        ' Let the DateTimePicker handle the keys listed.        Select Case key And Keys.KeyCode            Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, _                Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp                Return True            Case Else                Return Not dataGridViewWantsInputKey        End Select    End Function    Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) _        Implements IDataGridViewEditingControl.PrepareEditingControlForEdit        ' No preparation needs to be done.    End Sub    Public ReadOnly Property RepositionEditingControlOnValueChange() _        As Boolean Implements _        IDataGridViewEditingControl.RepositionEditingControlOnValueChange        Get            Return False        End Get    End Property    Public Property EditingControlDataGridView() As DataGridView _        Implements IDataGridViewEditingControl.EditingControlDataGridView        Get            Return dataGridViewControl        End Get        Set(ByVal value As DataGridView)            dataGridViewControl = value        End Set    End Property    Public Property EditingControlValueChanged() As Boolean _        Implements IDataGridViewEditingControl.EditingControlValueChanged        Get            Return valueIsChanged        End Get        Set(ByVal value As Boolean)            valueIsChanged = value        End Set    End Property    Public ReadOnly Property EditingControlCursor() As Cursor _        Implements IDataGridViewEditingControl.EditingPanelCursor        Get            Return MyBase.Cursor        End Get    End Property    Protected Overrides Sub OnValueChanged(ByVal eventargs As EventArgs)        ' Notify the DataGridView that the contents of the cell have changed.        valueIsChanged = True        Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)        MyBase.OnValueChanged(eventargs)    End SubEnd ClassPublic Class Form1    Inherits Form    Private dataGridView1 As New DataGridView()    <STAThreadAttribute()> _    Public Shared Sub Main()        Application.Run(New Form1())    End Sub    Public Sub New()        Me.dataGridView1.Dock = DockStyle.Fill        Me.Controls.Add(Me.dataGridView1)        Me.Text = "DataGridView calendar column demo"    End Sub    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _        Handles Me.Load        Dim col As New CalendarColumn()        Me.dataGridView1.Columns.Add(col)        Me.dataGridView1.RowCount = 5        Dim row As DataGridViewRow        For Each row In Me.dataGridView1.Rows            row.Cells(0).Value = DateTime.Now        Next row    End SubEnd Class
C#
复制代码
using System;using System.Windows.Forms;public class CalendarColumn : DataGridViewColumn{    public CalendarColumn() : base(new CalendarCell())    {    }    public override DataGridViewCell CellTemplate    {        get        {            return base.CellTemplate;        }        set        {            // Ensure that the cell used for the template is a CalendarCell.            if (value != null &&                 !value.GetType().IsAssignableFrom(typeof(CalendarCell)))            {                throw new InvalidCastException("Must be a CalendarCell");            }            base.CellTemplate = value;        }    }}public class CalendarCell : DataGridViewTextBoxCell{    public CalendarCell()        : base()    {        // Use the short date format.        this.Style.Format = "d";    }    public override void InitializeEditingControl(int rowIndex, object         initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)    {        // Set the value of the editing control to the current cell value.        base.InitializeEditingControl(rowIndex, initialFormattedValue,             dataGridViewCellStyle);        CalendarEditingControl ctl =             DataGridView.EditingControl as CalendarEditingControl;        ctl.Value = (DateTime)this.Value;    }    public override Type EditType    {        get        {            // Return the type of the editing contol that CalendarCell uses.            return typeof(CalendarEditingControl);        }    }    public override Type ValueType    {        get        {            // Return the type of the value that CalendarCell contains.            return typeof(DateTime);        }    }    public override object DefaultNewRowValue    {        get        {            // Use the current date and time as the default value.            return DateTime.Now;        }    }}class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl{    DataGridView dataGridView;    private bool valueChanged = false;    int rowIndex;    public CalendarEditingControl()    {        this.Format = DateTimePickerFormat.Short;    }    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue     // property.    public object EditingControlFormattedValue    {        get        {            return this.Value.ToShortDateString();        }        set        {            if (value is String)            {                this.Value = DateTime.Parse((String)value);            }        }    }    // Implements the     // IDataGridViewEditingControl.GetEditingControlFormattedValue method.    public object GetEditingControlFormattedValue(        DataGridViewDataErrorContexts context)    {        return EditingControlFormattedValue;    }    // Implements the     // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.    public void ApplyCellStyleToEditingControl(        DataGridViewCellStyle dataGridViewCellStyle)    {        this.Font = dataGridViewCellStyle.Font;        this.CalendarForeColor = dataGridViewCellStyle.ForeColor;        this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;    }    // Implements the IDataGridViewEditingControl.EditingControlRowIndex     // property.    public int EditingControlRowIndex    {        get        {            return rowIndex;        }        set        {            rowIndex = value;        }    }    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey     // method.    public bool EditingControlWantsInputKey(        Keys key, bool dataGridViewWantsInputKey)    {        // Let the DateTimePicker handle the keys listed.        switch (key & Keys.KeyCode)        {            case Keys.Left:            case Keys.Up:            case Keys.Down:            case Keys.Right:            case Keys.Home:            case Keys.End:            case Keys.PageDown:            case Keys.PageUp:                return true;            default:                return !dataGridViewWantsInputKey;        }    }    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit     // method.    public void PrepareEditingControlForEdit(bool selectAll)    {        // No preparation needs to be done.    }    // Implements the IDataGridViewEditingControl    // .RepositionEditingControlOnValueChange property.    public bool RepositionEditingControlOnValueChange    {        get        {            return false;        }    }    // Implements the IDataGridViewEditingControl    // .EditingControlDataGridView property.    public DataGridView EditingControlDataGridView    {        get        {            return dataGridView;        }        set        {            dataGridView = value;        }    }    // Implements the IDataGridViewEditingControl    // .EditingControlValueChanged property.    public bool EditingControlValueChanged    {        get        {            return valueChanged;        }        set        {            valueChanged = value;        }    }    // Implements the IDataGridViewEditingControl    // .EditingPanelCursor property.    public Cursor EditingPanelCursor    {        get        {            return base.Cursor;        }    }    protected override void OnValueChanged(EventArgs eventargs)    {        // Notify the DataGridView that the contents of the cell        // have changed.        valueChanged = true;        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);        base.OnValueChanged(eventargs);    }}public class Form1 : Form{    private DataGridView dataGridView1 = new DataGridView();    [STAThreadAttribute()]    public static void Main()    {        Application.Run(new Form1());    }    public Form1()    {        this.dataGridView1.Dock = DockStyle.Fill;        this.Controls.Add(this.dataGridView1);        this.Load += new EventHandler(Form1_Load);        this.Text = "DataGridView calendar column demo";    }    private void Form1_Load(object sender, EventArgs e)    {        CalendarColumn col = new CalendarColumn();        this.dataGridView1.Columns.Add(col);        this.dataGridView1.RowCount = 5;        foreach (DataGridViewRow row in this.dataGridView1.Rows)        {            row.Cells[0].Value = DateTime.Now;        }    }}

下面的示例需要:

  • 对 System 和 System.Windows.Forms 程序集的引用。

有关从 Visual Basic 或 Visual C# 的命令行生成此示例的信息,请参见从命令行生成 (Visual Basic) 或命令行生成。也可以通过将代码粘贴到新项目,在 Visual Studio 中生成此示例。

概念

自定义 Windows 窗体 DataGridView 控件
DataGridView 控件结构(Windows 窗体)
Windows 窗体 DataGridView 控件中的列类型

参考

DataGridView
DataGridViewColumn
DataGridViewCell
DataGridViewTextBoxCell
IDataGridViewEditingControl
DateTimePicker