About Modal Editor!
各位好,小弟有个问题,我针对User Control的Property的Modal Editor特性作了一些测试,发现Property用标准的Data Type(如int, bool, string)都OK,但Property若改用自定的Class,就有问题了, 状况如下:
1.将User Control从Tool Box拖曳到Form,然后在PropertyGrid中对该Class属性按下编辑钮,有时我自定的Editor Dialog会正常出现,但有时出不来,反而是出现Error Message!
2.User Control刚被拖曳到Form时,会发现Form的Designer档产生新的源码,但是当我按下编辑钮,并在Editor Dialog做了改变之后,按下OK钮,但Form的Designer档源码都没改变,反而是当我用滑鼠去改变User Control的大小后,Editor Dialog所做的改变及新的大小才真正反映在档案的源码上.
请问,是.NET这种应用不支援自定的Class,还是我的做法有错,谢谢!
using System;
using System.Collections.Generic;
using
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Design;
using System.Windows.Forms.Design;
namespace WindowsApplication4
{
public partial class My_Class_Test : UserControl
{
public My_Class_Test()
{
InitializeComponent();
}
[Editor(typeof(MyClassDataEditor), typeof(UITypeEditor))]
public MyClassData MyClass
{
get { return m_MyClass; }
set { m_MyClass = value; }
}
private MyClassData m_MyClass = new MyClassData();
}
[TypeConverter(typeof(MyClassDataConverter))]
public class MyClassData
{
private int m_Type;
public int Type
{
get { return m_Type; }
set { m_Type = value; }
}
//
private string m_Text;
public string Text
{
get { return m_Text; }
set { m_Text = value; }
}
//
private bool m_Visible;
public bool Visible
{
get { return m_Visible; }
set { m_Visible = value; }
}
}
class MyClassDataEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if ((context != null) && (provider != null))
{
// Access the Property Browser's UI display service
IWindowsFormsEditorService editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (editorService != null)
{
// Pass the UI editor dialog the current property value
MyClassData mydata = context.PropertyDescriptor.GetValue(context.Instance) as MyClassData;//(MyClassData)value;
// Create an instance of the UI editor form
MyClassEditDlg MyDlg = new MyClassEditDlg(mydata.Text, mydata.Type, mydata.Visible);
// Display the UI editor dialog
if (editorService.ShowDialog(MyDlg) == DialogResult.OK)
// Return the new property value from the UI editor form
//return modalEditor.My_Class;
{
mydata.Text = MyDlg.MyText;
mydata.Type = MyDlg.Type;
mydata.Visible = MyDlg.MyVisible;
return mydata;
}
}
}
return base.EditValue(context, provider, value);
}
}
public class MyClassDataConverter : ExpandableObjectConverter
{
public MyClassDataConverter()
{
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
string str = value as string;
if (str == null)
return base.ConvertFrom(context, culture, value);
string[] items = str.Split(";".ToCharArray());
if (items.Length != 3)
return base.ConvertFrom(context, culture, value);
MyClass1 myclass = context.PropertyDescriptor.GetValue(context.Instance) as MyClass1;
if (myclass == null)
return base.ConvertFrom(context, culture, value);
myclass.Text = items[0];
myclass.Type = int.Parse(items[1]);
myclass.Visible = bool.Parse(items[2]);
return myclass;
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
MyClass1 myclass = value as MyClass1;
if (myclass == null)
return base.ConvertTo(context, culture, value, destinationType);
return string.Format("{0},{1},{2}", myclass.Text, myclass.Type, myclass.Visible);
}
}
}