How do I change boolean properties with one click in PropertyGrid

时间:2016-06-06 14:19:35

标签: c# .net vb.net winforms propertygrid

We have a windows form types that we use to display all the properties. We have drawn a checkbox on Boolean property that checks it self and unchecks itself based on the value. this all works fine.

the issue is, that user wants to change the check box value in single click, whereas property grid changes it on a double click and I cant figure out a way to handle clicks or change property value on single click when property type is Boolean.

Any idea about how to change property value in single click will be helpful.

Thanks

2 个答案:

答案 0 :(得分:8)

PropertyGrid内部有一些方法可以让我们使用反射方法在点击GridItem内部控件时获取鼠标下的PropertyGridView

在下面的代码中,我在其PropertyGridView控件上单击鼠标并检查鼠标位置下的项是否是布尔属性,我将其反转了它的值。该事件将触发属性标签,也用于属性编辑器的图标区域:

enter image description here

<强> PropertyGrid的

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; }
}

答案 1 :(得分:0)

最佳答案是使用反射将GridItem放在鼠标下。但是,我认为这样做没有意义,因为它足以请求专用的GridItem。这是我对MouseClick的实现:

 void grid_MouseClick(object sender, MouseEventArgs e)
        {
            GridItem entry = SelectedGridItem;
            if (entry != null && entry.Value != null && entry.Value is bool b)
            {
                var obj = SelectedObjects.Length == 1 ? SelectedObject : SelectedObjects;
                entry.PropertyDescriptor.SetValue(obj, !b);
            }
        }