How do I change boolean properties with one click in PropertyGrid

混江龙づ霸主 提交于 2020-01-12 08:06:09

问题


We have a windows form PropertyGrid 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


回答1:


PropertyGrid internally has methods which allows us to use them with reflection to get the GridItem under mouse when you click on its PropertyGridView internal control.

In below code, I handled mouse click on its PropertyGridView control and checked if the item under mouse position is a boolean property, I reversed it's value. The event will fire for the label of property, also for icon area of the property editor:

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

Drawing CheckBox in PropertyGrid

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

Class which used in screenshot

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


来源:https://stackoverflow.com/questions/37659850/how-do-i-change-boolean-properties-with-one-click-in-propertygrid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!