This is the simplest ever custom property editor that contains just a form with one more 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
}
}
}
So, now I have a class:
class Test
{
public bool Prop1 { get; set; }
public bool Prop2 { get; set; }
}
And I have main class that has this Test
class as property.
class MainClass
{
[Editor(typeof(InnerPropertyGridEditor), typeof(UITypeEditor))]
public Test test_prop { get; set; }
...
}
My main PropertyEditor supports multi selected objects. So, I can select two or more MainClasses to edit their properties.
The problem is - when I do that and tries to edit test_prop
InnerPropertyGridEditor
appears empty, because of passed value is null.
Actually, I hoped it to be at least object[]
so I can implement something.
Ok, in case if no one will ever answer this I will show the hacky solution I made:
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
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.