DataGridView 控件包括 DataGridViewButtonCell 类,该类用于显示具有类似按钮的用户界面 (UI) 的单元格。但 DataGridViewButtonCell 不提供禁用由单元格显示的按钮外观的方式。
下面的代码示例演示如何自定义 DataGridViewButtonCell 类来显示可以显示为禁用的按钮。本示例定义一个新的单元格类型 DataGridViewDisableButtonCell,它由 DataGridViewButtonCell 派生。此单元格类型提供一个新的 Enabled 属性,可以将该属性设置为 false 来在单元格中绘制禁用的按钮。本示例还定义一个新的列类型 DataGridViewDisableButtonColumn,它显示 DataGridViewDisableButtonCell 对象。为了演示此新单元格类型和列类型,父 DataGridView 中的每个 DataGridViewCheckBoxCell 的当前值确定同一行中 DataGridViewDisableButtonCell 的 Enabled 属性是 true 还是 false。
注意 |
---|
当从 DataGridViewCell 或 DataGridViewColumn 派生并向派生类添加新属性时,请确保重写 Clone 方法以便在克隆操作期间复制新属性。还应调用基类的 Clone 方法,以便将基类的属性复制到新的单元格或列中。 |
示例
Imports System Imports System.Drawing Imports System.Windows.Forms Imports System.Windows.Forms.VisualStyles Class Form1 Inherits Form Private WithEvents dataGridView1 As New DataGridView() <STAThread()> _ Public Shared Sub Main() Application.EnableVisualStyles() Application.Run(New Form1()) End Sub Public Sub New() Me.AutoSize = True End Sub Public Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.Load Dim column0 As New DataGridViewCheckBoxColumn() Dim column1 As New DataGridViewDisableButtonColumn() column0.Name = "CheckBoxes" column1.Name = "Buttons" dataGridView1.Columns.Add(column0) dataGridView1.Columns.Add(column1) dataGridView1.RowCount = 8 dataGridView1.AutoSize = True dataGridView1.AllowUserToAddRows = False dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = _ DataGridViewContentAlignment.MiddleCenter ' Set the text for each button. Dim i As Integer For i = 0 To dataGridView1.RowCount - 1 dataGridView1.Rows(i).Cells("Buttons").Value = _ "Button " + i.ToString() Next i Me.Controls.Add(dataGridView1) End Sub ' This event handler manually raises the CellValueChanged event ' by calling the CommitEdit method. Sub dataGridView1_CurrentCellDirtyStateChanged( _ ByVal sender As Object, ByVal e As EventArgs) _ Handles dataGridView1.CurrentCellDirtyStateChanged If dataGridView1.IsCurrentCellDirty Then dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit) End If End Sub ' If a check box cell is clicked, this event handler disables ' or enables the button in the same row as the clicked cell. Public Sub dataGridView1_CellValueChanged(ByVal sender As Object, _ ByVal e As DataGridViewCellEventArgs) _ Handles dataGridView1.CellValueChanged If dataGridView1.Columns(e.ColumnIndex).Name = "CheckBoxes" Then Dim buttonCell As DataGridViewDisableButtonCell = _ CType(dataGridView1.Rows(e.RowIndex).Cells("Buttons"), _ DataGridViewDisableButtonCell) Dim checkCell As DataGridViewCheckBoxCell = _ CType(dataGridView1.Rows(e.RowIndex).Cells("CheckBoxes"), _ DataGridViewCheckBoxCell) buttonCell.Enabled = Not CType(checkCell.Value, [Boolean]) dataGridView1.Invalidate() End If End Sub ' If the user clicks on an enabled button cell, this event handler ' reports that the button is enabled. Sub dataGridView1_CellClick(ByVal sender As Object, _ ByVal e As DataGridViewCellEventArgs) _ Handles dataGridView1.CellClick If dataGridView1.Columns(e.ColumnIndex).Name = "Buttons" Then Dim buttonCell As DataGridViewDisableButtonCell = _ CType(dataGridView1.Rows(e.RowIndex).Cells("Buttons"), _ DataGridViewDisableButtonCell) If buttonCell.Enabled Then MsgBox(dataGridView1.Rows(e.RowIndex). _ Cells(e.ColumnIndex).Value.ToString() + _ " is enabled") End If End If End Sub End Class Public Class DataGridViewDisableButtonColumn Inherits DataGridViewButtonColumn Public Sub New() Me.CellTemplate = New DataGridViewDisableButtonCell() End Sub End Class Public Class DataGridViewDisableButtonCell Inherits DataGridViewButtonCell Private enabledValue As Boolean Public Property Enabled() As Boolean Get Return enabledValue End Get Set(ByVal value As Boolean) enabledValue = value End Set End Property ' Override the Clone method so that the Enabled property is copied. Public Overrides Function Clone() As Object Dim Cell As DataGridViewDisableButtonCell = _ CType(MyBase.Clone(), DataGridViewDisableButtonCell) Cell.Enabled = Me.Enabled Return Cell End Function ' By default, enable the button cell. Public Sub New() Me.enabledValue = True End Sub Protected Overrides Sub Paint(ByVal graphics As Graphics, _ ByVal clipBounds As Rectangle, ByVal cellBounds As Rectangle, _ ByVal rowIndex As Integer, _ ByVal elementState As DataGridViewElementStates, _ ByVal value As Object, ByVal formattedValue As Object, _ ByVal errorText As String, _ ByVal cellStyle As DataGridViewCellStyle, _ ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _ ByVal paintParts As DataGridViewPaintParts) ' The button cell is disabled, so paint the border, ' background, and disabled button for the cell. If Not Me.enabledValue Then ' Draw the background of the cell, if specified. If (paintParts And DataGridViewPaintParts.Background) = _ DataGridViewPaintParts.Background Then Dim cellBackground As New SolidBrush(cellStyle.BackColor) graphics.FillRectangle(cellBackground, cellBounds) cellBackground.Dispose() End If ' Draw the cell borders, if specified. If (paintParts And DataGridViewPaintParts.Border) = _ DataGridViewPaintParts.Border Then PaintBorder(graphics, clipBounds, cellBounds, cellStyle, _ advancedBorderStyle) End If ' Calculate the area in which to draw the button. Dim buttonArea As Rectangle = cellBounds Dim buttonAdjustment As Rectangle = _ Me.BorderWidths(advancedBorderStyle) buttonArea.X += buttonAdjustment.X buttonArea.Y += buttonAdjustment.Y buttonArea.Height -= buttonAdjustment.Height buttonArea.Width -= buttonAdjustment.Width ' Draw the disabled button. ButtonRenderer.DrawButton(graphics, buttonArea, _ PushButtonState.Disabled) ' Draw the disabled button text. If TypeOf Me.FormattedValue Is String Then TextRenderer.DrawText(graphics, CStr(Me.FormattedValue), _ Me.DataGridView.Font, buttonArea, SystemColors.GrayText) End If Else ' The button cell is enabled, so let the base class ' handle the painting. MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, _ elementState, value, formattedValue, errorText, _ cellStyle, advancedBorderStyle, paintParts) End If End Sub End Class
using System; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; class Form1 : Form { private DataGridView dataGridView1 = new DataGridView(); [STAThread] public static void Main() { Application.EnableVisualStyles(); Application.Run(new Form1()); } public Form1() { this.AutoSize = true; this.Load += new EventHandler(Form1_Load); } public void Form1_Load(object sender, EventArgs e) { DataGridViewCheckBoxColumn column0 = new DataGridViewCheckBoxColumn(); DataGridViewDisableButtonColumn column1 = new DataGridViewDisableButtonColumn(); column0.Name = "CheckBoxes"; column1.Name = "Buttons"; dataGridView1.Columns.Add(column0); dataGridView1.Columns.Add(column1); dataGridView1.RowCount = 8; dataGridView1.AutoSize = true; dataGridView1.AllowUserToAddRows = false; dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; // Set the text for each button. for (int i = 0; i < dataGridView1.RowCount; i++) { dataGridView1.Rows[i].Cells["Buttons"].Value = "Button " + i.ToString(); } dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged); dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged); dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick); this.Controls.Add(dataGridView1); } // This event handler manually raises the CellValueChanged event // by calling the CommitEdit method. void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) { if (dataGridView1.IsCurrentCellDirty) { dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); } } // If a check box cell is clicked, this event handler disables // or enables the button in the same row as the clicked cell. public void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.Columns[e.ColumnIndex].Name == "CheckBoxes") { DataGridViewDisableButtonCell buttonCell = (DataGridViewDisableButtonCell)dataGridView1. Rows[e.RowIndex].Cells["Buttons"]; DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)dataGridView1. Rows[e.RowIndex].Cells["CheckBoxes"]; buttonCell.Enabled = !(Boolean)checkCell.Value; dataGridView1.Invalidate(); } } // If the user clicks on an enabled button cell, this event handler // reports that the button is enabled. void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.Columns[e.ColumnIndex].Name == "Buttons") { DataGridViewDisableButtonCell buttonCell = (DataGridViewDisableButtonCell)dataGridView1. Rows[e.RowIndex].Cells["Buttons"]; if (buttonCell.Enabled) { MessageBox.Show(dataGridView1.Rows[e.RowIndex]. Cells[e.ColumnIndex].Value.ToString() + " is enabled"); } } } } public class DataGridViewDisableButtonColumn : DataGridViewButtonColumn { public DataGridViewDisableButtonColumn() { this.CellTemplate = new DataGridViewDisableButtonCell(); } } public class DataGridViewDisableButtonCell : DataGridViewButtonCell { private bool enabledValue; public bool Enabled { get { return enabledValue; } set { enabledValue = value; } } // Override the Clone method so that the Enabled property is copied. public override object Clone() { DataGridViewDisableButtonCell cell = (DataGridViewDisableButtonCell)base.Clone(); cell.Enabled = this.Enabled; return cell; } // By default, enable the button cell. public DataGridViewDisableButtonCell() { this.enabledValue = true; } protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { // The button cell is disabled, so paint the border, // background, and disabled button for the cell. if (!this.enabledValue) { // Draw the cell background, if specified. if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background) { SolidBrush cellBackground = new SolidBrush(cellStyle.BackColor); graphics.FillRectangle(cellBackground, cellBounds); cellBackground.Dispose(); } // Draw the cell borders, if specified. if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border) { PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); } // Calculate the area in which to draw the button. Rectangle buttonArea = cellBounds; Rectangle buttonAdjustment = this.BorderWidths(advancedBorderStyle); buttonArea.X += buttonAdjustment.X; buttonArea.Y += buttonAdjustment.Y; buttonArea.Height -= buttonAdjustment.Height; buttonArea.Width -= buttonAdjustment.Width; // Draw the disabled button. ButtonRenderer.DrawButton(graphics, buttonArea, PushButtonState.Disabled); // Draw the disabled button text. if (this.FormattedValue is String) { TextRenderer.DrawText(graphics, (string)this.FormattedValue, this.DataGridView.Font, buttonArea, SystemColors.GrayText); } } else { // The button cell is enabled, so let the base class // handle the painting. base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); } } }
编译代码
此示例要求:
-
对 System、System.Drawing、System.Windows.Forms 和 System.Windows.Forms.VisualStyles 程序集的引用。
有关从 Visual Basic 或 Visual C# 的命令行生成此示例的信息,请参见从命令行生成 (Visual Basic) 或命令行生成。也可以通过将代码粘贴到新项目,在 Visual Studio 中生成此示例。 有关更多信息,请参见 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例.
请参见
概念
DataGridView 控件结构(Windows 窗体)Windows 窗体 DataGridView 控件中的列类型