Se trata de un complemento a la respuesta de Jay.
Por solicitud, aquí está el código que utilicé para crear una celda de botón que podría ser deshabilitada. Incluye doble buffering para que los botones no parpadeen cuando el usuario se desplaza.
/// <summary>
/// Adapted from https://msdn.microsoft.com/en-us/library/ms171619.aspx. Double-buffering was added to remove flicker on re-paints.
/// </summary>
public class DataGridViewDisableButtonCell : DataGridViewButtonCell
{
private bool enabledValue;
public bool Enabled
{
get { return enabledValue; }
set
{
if (enabledValue == value) return;
enabledValue = value;
// force the cell to be re-painted
if (DataGridView != null) DataGridView.InvalidateCell(this);
}
}
// Override the Clone method so that the Enabled property is copied.
public override object Clone()
{
var cell = (DataGridViewDisableButtonCell) base.Clone();
cell.Enabled = Enabled;
return cell;
}
// By default, enable the button cell.
public DataGridViewDisableButtonCell()
{
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 (!enabledValue)
{
var currentContext = BufferedGraphicsManager.Current;
using (var myBuffer = currentContext.Allocate(graphics, cellBounds))
{
// Draw the cell background, if specified.
if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background)
{
using (var cellBackground = new SolidBrush(cellStyle.BackColor))
{
myBuffer.Graphics.FillRectangle(cellBackground, cellBounds);
}
}
// Draw the cell borders, if specified.
if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border)
{
PaintBorder(myBuffer.Graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
}
// Calculate the area in which to draw the button.
var buttonArea = cellBounds;
var buttonAdjustment = BorderWidths(advancedBorderStyle);
buttonArea.X += buttonAdjustment.X;
buttonArea.Y += buttonAdjustment.Y;
buttonArea.Height -= buttonAdjustment.Height;
buttonArea.Width -= buttonAdjustment.Width;
// Draw the disabled button.
ButtonRenderer.DrawButton(myBuffer.Graphics, buttonArea, PushButtonState.Disabled);
// Draw the disabled button text.
var formattedValueString = FormattedValue as string;
if (formattedValueString != null)
{
TextRenderer.DrawText(myBuffer.Graphics, formattedValueString, DataGridView.Font, buttonArea, SystemColors.GrayText, TextFormatFlags.PreserveGraphicsTranslateTransform | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}
myBuffer.Render();
}
}
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);
}
}
}
¿Por qué no es la capacidad de desactivar un botón allí de forma predeterminada, me pregunto? – Coops
El método 'DataGridViewDisableButtonCell.Paint()' en el artículo de MSDN parpadea en repintados (sin doble almacenamiento en búfer). Para remediar, modifique su implementación utilizando [este artículo] (https://msdn.microsoft.com/en-us/library/ka0yazs1 (v = vs.110) .aspx) como guía. Crea un objeto BufferedGraphics (por ejemplo, 'myBuffer'), reemplaza los usos de' graphics' con 'myBuffer.Graphics', y luego llama a' myBuffer.Render() 'al final. Advertencia: La llamada a 'TextRenderer.DrawText()' DEBE especificar estos indicadores de formato de texto para colocar correctamente el texto del botón: 'PreserveGraphicsTranslateTransform | HorizontalCenter | VerticalCenter' –
La solución en este enlace tampoco cubre el relleno en su CellStyle. Puede modificar el Método de pintura para incorporar cualquier Relleno presente en el "estilo de celda" agregando el Relleno.Valor horizontal para ajustar.Anchura de botones y Relleno.Valor vertical para ajustar botones.Altura y agregando Relleno de estilo de celda.Adelante a botónAjuste.X y Padding de cellStyle. Ajuste superior a button.Y. –