#c# #.net #winforms #propertygrid
#c# #.net #winforms #сетка свойств
Вопрос:
Я хотел бы получить доступ к object
объектам через PropertyGrid и заставить их вести себя так, как они представляют на самом деле. Для игрушечного класса, такого как;
[TypeConverter(typeof(ObjectBucket.ObjectBucketConverter))]
class ObjectBucket
{
public object foo;
[Browsable(true)]
public object Object
{
get { return foo; }
set { foo = value; }
}
private class ObjectBucketConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType);
}
}
}
я хотел бы иметь возможность установить, скажем, a float
через средство доступа к объекту, а затем заставить его вести себя как a float
в PropertyGrid, а не стандартное object
поведение, заключающееся в возможности ничего с ним не делать.
В качестве обходного пути я ввел следующий метод доступа в;
[Browsable(true)]
public string ObjectStr
{
get { return foo.ToString(); }
set
{
try
{
foo = TypeDescriptor.GetConverter(foo.GetType()).ConvertFromInvariantString(value);
}
catch
{
return;
}
}
}
что позволяет мне манипулировать объектом, но это не идеально. Возможно ли вообще то, что я хочу сделать?
Ответ №1:
Это возможно. Вам необходимо реализовать ICustomTypeDescriptor
и предоставить свои собственные экземпляры PropertyDescriptors
(в System.ComponentModel
) — в этих дескрипторах свойств вы можете указать тип свойства — в вашем случае float.
Ответ №2:
Я предлагаю вам реализовать свой собственный редактор типов для ObjectBucket.Свойство объекта. Это позволит вам отобразить форму редактора, в которой пользователь может указать тип и значение для этого свойства следующим образом:
Вот скелет реализации:
class ObjectBucket {
object foo;
[Editor(typeof(ObjectUITypeEditor), typeof(UITypeEditor))]
public object Object {
get { return foo; }
set { foo = value; }
}
}
//...
class ObjectUIEditor : Form {
public ObjectUIEditor(object editValue) {
/* TODO Initialize editor*/
}
public object EditValue {
get { return null; /* TODO GetValue from editor */}
}
}
//...
class ObjectUITypeEditor : System.Drawing.Design.UITypeEditor {
System.Windows.Forms.Design.IWindowsFormsEditorService edSvc = null;
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object objValue)
if(context != null amp;amp; context.Instance != null amp;amp; provider != null) {
edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if(edSvc != null) {
try {
ObjectUIEditor editor = new ObjectUIEditor(objValue);
if(edSvc.ShowDialog(editor) == DialogResult.OK)
objValue = editor.EditValue;
}
catch { }
}
}
return objValue;
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
if(context != null amp;amp; context.Instance != null)
return UITypeEditorEditStyle.Modal;
return base.GetEditStyle(context);
}
}