繁体   English   中英

如何为PropertyGrid的自定义属性编辑器添加对多对象编辑的支持?

[英]How to add support of multiobject edits for PropertyGrid's custom property editor?

这是有史以来最简单的自定义属性编辑器,仅包含带有一个PropertyGrid的表单:

using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;

namespace PageControls
{
    public partial class PropertyGridEditor : Form
    {
        public object ObjectToEdit;

        public delegate void PropertyValueChangedEventHandler(object sender, PropertyValueChangedEventArgs e);
        public static event PropertyValueChangedEventHandler PropertyValueChangedStatic;
        public event EventHandler<PropertyValueChangedEventArgs> PropertyValueChanged;

        public PropertyGridEditor(object obj_to_edit)
        {
            InitializeComponent();
            this.ObjectToEdit = obj_to_edit;
        }

        private void PropertyGridEditor_Load(object sender, EventArgs e)
        {
            this.prop_grid.SelectedObject = ObjectToEdit;
        }

        private void PropertyGridEditor_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        private void prop_grid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            var evt = PropertyGridEditor.PropertyValueChangedStatic;

            if (evt != null)
                evt(s, e);

            var evt2 = this.PropertyValueChanged;

            if (evt2 != null)
                evt2(s, e);
        }
    }

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class InnerPropertyGridEditor : UITypeEditor
    {
        public InnerPropertyGridEditor()
        {

        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            // Indicates that this editor can display a Form-based interface. 
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            // Attempts to obtain an IWindowsFormsEditorService.
            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

            if (edSvc == null)
                return null;

            using (PropertyGridEditor form = new PropertyGridEditor(value)) //when two or more properties were selected the value is null :/
                if (edSvc.ShowDialog(form) == DialogResult.OK)
                    return form.ObjectToEdit;

            return value; // If OK was not pressed, return the original value 
        }
    }
}

所以,现在我有一堂课:

class Test
{
   public bool Prop1 { get; set; }
   public bool Prop2 { get; set; }
}

我有主类具有此Test类作为属性。

class MainClass
{
    [Editor(typeof(InnerPropertyGridEditor), typeof(UITypeEditor))]
    public Test test_prop { get; set; }

    ...
}

我的主要PropertyEditor支持多个选定的对象。 因此,我可以选择两个或多个MainClasses来编辑其属性。

问题是-当我这样做并尝试编辑test_prop InnerPropertyGridEditor显示为空,因为传递的值为null。

实际上,我希望它至少是object[]以便我可以实现一些东西。

好吧,以防万一没人能回答这个问题,我将展示我做的hacky解决方案:

using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Reflection;

namespace PageControls
{
    public partial class PropertyGridEditor : Form
    {
        public object Result;

        public static event EventHandler<PropertyValueChangedEventArgs> PropertyValueChangedStatic;
        public event EventHandler<PropertyValueChangedEventArgs> PropertyValueChanged;

        public PropertyGridEditor(object[] obj_to_edit)
        {
            InitializeComponent();

            this.prop_grid.SelectedObjects = obj_to_edit;

            this.Result = obj_to_edit[0];
        }

        private void PropertyGridEditor_Load(object sender, EventArgs e)
        {

        }

        private void PropertyGridEditor_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        private void prop_grid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            var evt = PropertyGridEditor.PropertyValueChangedStatic;

            if (evt != null)
                evt(s, e);

            var evt2 = this.PropertyValueChanged;

            if (evt2 != null)
                evt2(s, e);
        }
    }

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class InnerPropertyGridEditor : UITypeEditor
    {
        public InnerPropertyGridEditor()
        {

        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            // Indicates that this editor can display a Form-based interface. 
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            // Attempts to obtain an IWindowsFormsEditorService.
            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

            if (edSvc == null)
                return null;

            object[] values = new object[context.Instance is object[] ? ((object[])context.Instance).Length : 1];

            if (context.Instance is object[])
                for (int i = 0; i < ((object[])context.Instance).Length; i++)
                {
                    PropertyInfo pi = ((object[])context.Instance)[i].GetType().GetProperty(context.PropertyDescriptor.Name);
                    values[i] = pi != null ? pi.GetValue(((object[])context.Instance)[i], null) : null;
                }
            else
                values[0] = value;

            using (PropertyGridEditor form = new PropertyGridEditor(values))
                if (edSvc.ShowDialog(form) == DialogResult.OK)
                    return form.Result;

            return value; // If OK was not pressed, return the original value 
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM