c# - 如何在 PropertyGrid 中一键更改 bool 属性

标签 c# .net vb.net winforms propertygrid

我们有一个窗口窗体 PropertyGrid 用来显示所有属性。我们在 Boolean 属性上绘制了一个复选框,它会根据值自行选中并取消选中。这一切都很好。

问题是,用户想通过单击更改复选框值,而属性网格通过双击更改它,我无法想出一种方法来处理单击或在属性类型为 bool 值。

如何通过单击更改属性值?

最佳答案

PropertyGrid内部有一些方法,当您单击其 PropertyGridView 内部控件时,我们可以通过反射使用它们来获取鼠标下的 GridItem

在下面的代码中,我处理了鼠标点击其 PropertyGridView 控件并检查鼠标位置下的项目是否为 bool 属性,我反转了它的值。该事件将针对属性标签以及属性编辑器的图标区域触发:

enter image description here

属性网格

using System;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
public class ExPropertyGrid : PropertyGrid
{
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        var grid = this.Controls[2];
        grid.MouseClick += grid_MouseClick;
    }
    void grid_MouseClick(object sender, MouseEventArgs e)
    {
        var grid = this.Controls[2];
        var flags = BindingFlags.Instance | BindingFlags.NonPublic;
        var invalidPoint = new Point(-2147483648, -2147483648);
        var FindPosition = grid.GetType().GetMethod("FindPosition", flags);
        var p = (Point)FindPosition.Invoke(grid, new object[] { e.X, e.Y });
        GridItem entry = null;
        if (p != invalidPoint) {
            var GetGridEntryFromRow = grid.GetType()
                                          .GetMethod("GetGridEntryFromRow", flags);
            entry = (GridItem)GetGridEntryFromRow.Invoke(grid, new object[] { p.Y });
        }
        if (entry != null && entry.Value != null) {
            object parent;
            if (entry.Parent != null && entry.Parent.Value != null)
                parent = entry.Parent.Value;
            else
                parent = this.SelectedObject;
            if (entry.Value != null && entry.Value is bool) {
                entry.PropertyDescriptor.SetValue(parent,!(bool)entry.Value);
                this.Refresh();
            }
        }
    }
}

在PropertyGrid中绘制CheckBox

public class MyBoolEditor : UITypeEditor
{
    public override bool GetPaintValueSupported
        (System.ComponentModel.ITypeDescriptorContext context)
    { return true; }
    public override void PaintValue(PaintValueEventArgs e)
    {
        var rect = e.Bounds;
        rect.Inflate(1, 1);
        ControlPaint.DrawCheckBox(e.Graphics, rect, ButtonState.Flat |
            (((bool)e.Value) ? ButtonState.Checked : ButtonState.Normal));
    }
}

截图中使用的类

public class Model
{
    public int Property1 { get; set; }
    [Editor(typeof(MyBoolEditor), typeof(UITypeEditor))]
    public bool Property2 { get; set; }

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public Model Property3 { get; set; }
}

关于c# - 如何在 PropertyGrid 中一键更改 bool 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37659850/

相关文章:

c# - 在 C# 中使用 Moq 测试回调

c# - 将复杂参数传递给 [Theory]

c# - PLINQ 异常

vb.net - VB.NET-将MP3转换为Base64字符串

javascript - 如何使用VB.Net通过javascript变量将JSON对象插入Mysql数据库

c# - 从 C# 窗体启动 VB 窗体

c# - 如何将单个 ObjectContext 用于多种类型的数据库?

c# - 如果值存在则更新,否则将值插入数据库

.net - 如何模拟 RIA 服务

c# - 在窗口服务中检测关闭