如何创建打开表单的自定义通用PropertyGrid编辑器项?

时间:2017-10-28 20:16:49

标签: c# winforms generics propertygrid uitypeeditor

我有一个自定义通用表单

 public partial class MyTestForm1 : MyBrowseForm<CONTACTS_BASE>

其中CONTACTS_BASE是EntityFramework实体。

在父类上我希望有一个属性,这样当我在设计师时间从属性网格点击它时,它会打开一个表单,在那个表单上我想要一个组合框填充CONTACTS_BASE上的字段实体。

我找到了这篇文章 Marc Gravell's answer帮助我在设计时单击属性时打开一个新表单,并且我还使用CONTACTS_BASE字段填充了ComboBox。但是为了在表单加载事件上执行此操作,我调用了函数,它返回字段列表并将其设置为ComboBox的数据源。

comboBox1.DataSource = EntityBase.BaseGetTableFieldList2<CONTACTS_BASE>();

enter image description here

然而,我想要完成的是制作这个通用的

所以我想做的就是填充ComboBox。

public partial class BdEditorForm <TParentEntity>:Form where TParentEntity:class
{
    private void BdEditorForm_Load(object sender, EventArgs e)
    {       
     comboBox1.DataSource = EntityBase.BaseGetTableFieldList2<TParentEntity>();
    }
}

是这样的吗?因为我试图这样做 我需要使TypeEditor也是通用的,然后在为我创建的属性提供属性时

[Editor(typeof(BdFormTypeEditor<TParentEntity>), typeof(UITypeEditor))]
[TypeConverter(typeof(ExpandableObjectConverter))]

并说:enter image description here

感谢任何帮助,感谢抱歉我的英语不好

1 个答案:

答案 0 :(得分:1)

简答

要知道如何解决问题,您需要知道EditValue方法有一个context参数,其类型为ITypeDescriptorContext并且具有Instance属性,即您正在编辑的属性的所有者对象。拥有所有者(表单)我们知道表单的类型,因此我们知道通用参数类型,因此我们可以创建我们的通用编辑器表单。

分步示例

以上事实是答案的关键点,但要解决问题,你还需要应用其他一些技巧。例如,您应该获得泛型类型并使用反射创建它的实例。

这里我放了一个包含示例的完整源代码的项目:

以下是创建自定义模型UI类型编辑器的示例的步骤,以便在编辑从T派生的表单的特定属性时显示MyBaseForm<T>的属性列表。

通用基本表格

它是包含SomeProperty的其他表单的基本表单,您希望使用自定义编辑器编辑该属性。

向返回MyGenericType的类添加typeof(T)属性,该类是表单的泛型类型:

public partial class MyBaseForm<T> : Form
{
    public MyBaseForm()
    {
        InitializeComponent();
    }

    [Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))]
    public string SomeProperty { get; set; }

    [Browsable(false)]
    public Type MyGenericType { get { return typeof(T); } }
}

派生表格

这是一个衍生自MyBaseForm<T>的样本派生形式。我们将编辑此类实例的SomeProperty

public partial class MyDerivedForm : MyBaseForm<MySampleModel>
{
    public MyDerivedForm()
    {
        InitializeComponent();
    }
}

样本模型

这是一个示例模型,我们将在自定义编辑器窗口中显示其属性。

public class MySampleModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Price { get; set; }
}

编辑表格

这是UITypeEditor将展示的形式。在表单中,我们使用泛型参数的字段名称填充comoBox1

public partial class MyEditorForm<T> : Form
{
    public MyEditorForm()
    {
        InitializeComponent();
        this.StartPosition = FormStartPosition.CenterScreen;
        var list = ListBindingHelper.GetListItemProperties(typeof(T))
            .Cast<PropertyDescriptor>()
            .Select(x => new { Text = x.Name, Value = x }).ToList();
        this.comboBox1.DataSource = list;
        this.comboBox1.DisplayMember = "Text";
        this.comboBox1.ValueMember = "Value";
    }
    public string SelectedProperty
    {
        get
        {
            return comboBox1.GetItemText(comboBox1.SelectedItem);
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.OK;
    }
}

UI类型编辑器

在调用EditValue的{​​{1}}方法时,UITypeEditor参数属于context类型,其属性为System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry,其值为实例您正在编辑的表单,因此我们知道表单的类型,因此我们知道通用参数类型,因此我们可以创建我们的通用编辑器表单并使用它。

Component