首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更改“数据视图”复选框单元格的checkBox大小并增加可单击区域

更改“数据视图”复选框单元格的checkBox大小并增加可单击区域
EN

Stack Overflow用户
提问于 2022-08-31 04:38:39
回答 1查看 82关注 0票数 1

我的.net核心Winform中有一个复选框列。

我已经做了更大的复选框,使用户更容易单击。

我在CellPainting里面的代码,

代码语言:javascript
运行
复制
                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#

结果如下,

但是问题是点击区域,即使复选框的大小更大,我也意识到可点击区域仍然在原来的大小。

如下所示,绿色区域是可点击的区域,

我想让这个可点击的区域和复选框的大小一样大,如下所示,

有什么解决办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-31 13:35:57

当您单击一个DataGridViewCheckBoxCell以切换选中的状态时,您必须单击单元格内的content,单击该单元格内的其他位置不会改变任何事情。DataGridViewCheckBoxCell的内容就是那个小的盒子区域。因此,仅仅绘制一个更大的框并不会调整内容区域的大小或重新定位(根据列的DefaultCellStyle.Alignment),并且保持不变。您需要编写代码来判断,内容区域已经被单击,相关的基本方法和事件应该被调用。

我会创建自定义的DataGridViewCheckBox列和单元格来应用这个要求。

在项目名称空间中,从DataGridViewCheckBoxColumn派生一个新类

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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并手动添加列。例如:

代码语言:javascript
运行
复制
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;

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73550925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档