首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为PropertyGrid的自定义属性编辑器添加对多对象编辑的支持?

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

Stack Overflow用户
提问于 2015-03-20 16:30:13
回答 1查看 273关注 0票数 0

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

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

所以,现在我有一个类:

代码语言:javascript
复制
class Test
{
   public bool Prop1 { get; set; }
   public bool Prop2 { get; set; }
}

我有一个主类,它将这个Test类作为属性。

代码语言:javascript
复制
class MainClass
{
    [Editor(typeof(InnerPropertyGridEditor), typeof(UITypeEditor))]
    public Test test_prop { get; set; }

    ...
}

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

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

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

EN

回答 1

Stack Overflow用户

发布于 2015-03-20 17:48:26

好的,如果没有人回答这个问题,我将展示我制作的解决方案:

代码语言:javascript
复制
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 
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29162324

复制
相关文章

相似问题

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