如何:停用 Windows Form DataGridView 控制項按鈕資料行中的按鈕
DataGridView 控制項包含 DataGridViewButtonCell 類別,可使用按鈕等使用者介面 (UI) 來顯示儲存格。 但是,DataGridViewButtonCell 未提供任何方法,來停用儲存格所顯示的按鈕外觀。
下列程式碼範例示範如何自訂 DataGridViewButtonCell 類別,來顯示可呈現為停用狀態的按鈕。 這個範例會定義新的儲存格類型 DataGridViewDisableButtonCell
,這個類型衍生自 DataGridViewButtonCell。 這個儲存格類型提供了新的 Enabled
屬性,可設定為 false
,以便在儲存格中繪製停用的按鈕。 這個範例也會定義新的資料行類型 DataGridViewDisableButtonColumn
,以顯示 DataGridViewDisableButtonCell
物件。 為了示範這個新的儲存格和資料行類型,在父 DataGridView 中每個 DataGridViewCheckBoxCell 的目前值會決定同一個資料列中 DataGridViewDisableButtonCell
的 Enabled
屬性是 true
或 false
。
注意
當您自 DataGridViewCell 或 DataGridViewColumn 中衍生時,以及在衍生類別中加入新的屬性時,請務必覆寫 Clone
方法,在複製作業期間複製新的屬性。 您也應該呼叫基底類別的 Clone
方法,以便將基底類別的屬性複製到新的儲存格或資料行。
範例
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);
}
}
}
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
編譯程式碼
這個範例需要:
- System、System.Drawing、System.Windows.Forms 和 System.Windows.Forms.VisualStyles 組件的參考。