我的.net核心Winform中有一个复选框列。
我已经做了更大的复选框,使用户更容易单击。
我在CellPainting
里面的代码,
e.PaintBackground(e.CellBounds, true);
ControlPaint.DrawCheckBox(e.Graphics, e.CellBounds.X + 1, e.CellBounds.Y + 5,
e.CellBounds.Width - 10, e.CellBounds.Height - 10,
(bool)e.FormattedValue ? ButtonState.Checked : ButtonState.Normal);
e.Handled = true;
这些是我的参考链接,
How to change checkBox Size in DatagridviewCheckboxCell
Increase the size of Checkbox in #DataGridView in C#
结果如下,
但是问题是点击区域,即使复选框的大小更大,我也意识到可点击区域仍然在原来的大小。
如下所示,绿色区域是可点击的区域,
我想让这个可点击的区域和复选框的大小一样大,如下所示,
有什么解决办法吗?
发布于 2022-08-31 13:35:57
当您单击一个DataGridViewCheckBoxCell
以切换选中的状态时,您必须单击单元格内的content,单击该单元格内的其他位置不会改变任何事情。DataGridViewCheckBoxCell
的内容就是那个小的盒子区域。因此,仅仅绘制一个更大的框并不会调整内容区域的大小或重新定位(根据列的DefaultCellStyle.Alignment
),并且保持不变。您需要编写代码来判断,内容区域已经被单击,相关的基本方法和事件应该被调用。
我会创建自定义的DataGridViewCheckBox
列和单元格来应用这个要求。
在项目名称空间中,从DataGridViewCheckBoxColumn
派生一个新类
public class CustomDataGridViewCheckBoxColumn : DataGridViewCheckBoxColumn
{
public CustomDataGridViewCheckBoxColumn() : base() =>
CellTemplate = new CustomDataGridViewCheckBoxCell();
public override DataGridViewCell CellTemplate
{
get => base.CellTemplate;
set
{
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(CustomDataGridViewCheckBoxCell)))
throw new InvalidCastException("CustomDataGridViewCheckBoxCell.");
base.CellTemplate = value;
}
}
[Category("Appearance")]
[DefaultValue(typeof(Size), "17, 17")]
[Description("The size of the check box.")]
public Size CheckBoxSize { get; set; } = new Size(17, 17);
// We should copy the new properties.
public override object Clone()
{
var c = base.Clone() as CustomDataGridViewCheckBoxColumn;
c.CheckBoxSize = CheckBoxSize;
return c;
}
}
另一个来源于DataGridViewCheckBoxCell
public class CustomDataGridViewCheckBoxCell : DataGridViewCheckBoxCell
{
private Rectangle curCellBounds;
private Rectangle checkBoxRect;
public CustomDataGridViewCheckBoxCell() : base() { }
protected override void Paint(
Graphics g,
Rectangle clipBounds,
Rectangle cellBounds,
int rowIndex,
DataGridViewElementStates elementState,
object value,
object formattedValue,
string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
// Paint default except the check box parts.
var parts = paintParts & ~(DataGridViewPaintParts.ContentForeground
| DataGridViewPaintParts.ContentBackground);
base.Paint(g,
clipBounds,
cellBounds,
rowIndex,
elementState,
value,
formattedValue,
errorText,
cellStyle,
advancedBorderStyle,
parts);
if (curCellBounds != cellBounds)
{
// To get the box size...
var col = OwningColumn as CustomDataGridViewCheckBoxColumn;
curCellBounds = cellBounds;
// ToDo: Use col.DefaultCellStyle.Alignment or
// DataGridView.ColumnHeadersDefaultCellStyle.Alignment
// to position the box. MiddleCenter here...
checkBoxRect = new Rectangle(
(cellBounds.Width - col.CheckBoxSize.Width) / 2 + cellBounds.X,
(cellBounds.Height - col.CheckBoxSize.Height) / 2 + cellBounds.Y,
col.CheckBoxSize.Width,
col.CheckBoxSize.Height);
}
ControlPaint.DrawCheckBox(g, checkBoxRect, (bool)formattedValue
? ButtonState.Checked | ButtonState.Flat
: ButtonState.Flat);
}
// In case you don't use the `Alignment` property to position the
// box. This is to disallow toggling the state if you click on the
// original content area outside the drawn box.
protected override void OnContentClick(DataGridViewCellEventArgs e)
{
if (!ReadOnly &&
checkBoxRect.Contains(DataGridView.PointToClient(Cursor.Position)))
base.OnContentClick(e);
}
protected override void OnContentDoubleClick(DataGridViewCellEventArgs e)
{
if (!ReadOnly &&
checkBoxRect.Contains(DataGridView.PointToClient(Cursor.Position)))
base.OnContentDoubleClick(e);
}
// Toggle the checked state by mouse clicks...
protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
{
base.OnMouseUp(e);
if (!ReadOnly && e.Button == MouseButtons.Left &&
checkBoxRect.Contains(DataGridView.PointToClient(Cursor.Position)))
{
Value = Value == null || !Convert.ToBoolean(Value);
DataGridView.RefreshEdit();
DataGridView.NotifyCurrentCellDirty(true);
}
}
// ... and Space key...
protected override void OnKeyDown(KeyEventArgs e, int rowIndex)
{
base.OnKeyDown(e, rowIndex);
if (!ReadOnly && e.KeyCode == Keys.Space)
{
Value = Value == null || !Convert.ToBoolean(Value.ToString());
DataGridView.RefreshEdit();
DataGridView.NotifyCurrentCellDirty(true);
}
}
}
重新生成并签出网格设计器中的新列类型。
如果有数据绑定网格,请将AutoGenerateColumns
属性设置为false
并手动添加列。例如:
private readonly static Random rnd = new Random();
//..
var dt = new DataTable();
dt.Columns.AddRange(new[]
{
new DataColumn("Default", typeof(bool)),
new DataColumn("Custom", typeof(bool))
});
for (int i = 1; i < 6; i++)
dt.Rows.Add(rnd.Next(0, 2), rnd.Next(0, 2));
dataGridView1.AutoGenerateColumns = false;
dataGridView1.Columns.AddRange(new[]
{
new DataGridViewCheckBoxColumn { HeaderText = "Default" },
new CustomDataGridViewCheckBoxColumn
{
HeaderText = "Custom",
CheckBoxSize = new Size(32, 32)
}
});
dataGridView1.DataSource = dt;
https://stackoverflow.com/questions/73550925
复制相似问题