简体   繁体   English

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

[英]How to create custom generic PropertyGrid editor item which opens a form?

I have a custom generic form我有一个自定义的通用表单

 public partial class MyTestForm1 : MyBrowseForm<CONTACTS_BASE>

where CONTACTS_BASE is an EntityFramework entity.其中 CONTACTS_BASE 是一个 EntityFramework 实体。

on the parent class I would like to have a property so that when I click on it at designer time from the property grid it opens a form and on that form I would like to have a combobox populated with the fields on the CONTACTS_BASE entity.在父类上,我想要一个属性,这样当我在设计器时从属性网格中单击它时,它会打开一个表单,在该表单上我想要一个组合框,其中包含 CONTACTS_BASE 实体上的字段。

I have found this post Marc Gravell's answer helped me to open a new form when clicked on the property at design time and I have also populated the ComboBox with fields of CONTACTS_BASE.我发现这篇文章Marc Gravell 的回答帮助我在设计时单击属性时打开了一个新表单,并且我还使用 CONTACTS_BASE 字段填充了 ComboBox。 but to do this on the form load event I called to function I made to that returns the list of fields and set it to ComboBox's DataSource.但要在表单加载事件上执行此操作,我调用了我所做的函数,该函数返回字段列表并将其设置为 ComboBox 的数据源。

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

在此处输入图片说明

however what I would like to accomplish is making this generic但是我想完成的是使这个通用

so what I would like to do is something like this to populate the ComboBox.所以我想做的是这样的事情来填充 ComboBox。

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

is something like this possible?这样的事情可能吗? because When I try to do this I need to make make TypeEditor generic too and then when giving attributes to the property I create因为当我尝试这样做时,我也需要使 TypeEditor 通用,然后在为我创建的属性赋予属性时

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

and it says:它说: 在此处输入图片说明

any help is appreciated thanks and sorry for my bad english任何帮助表示感谢感谢和抱歉我的英语不好

Short Answer简答

To know how to solve the problem, you need to know EditValue method has a context parameter which is of type ITypeDescriptorContext and has an Instance property which is the owner object of the property that you are editing.要知道如何解决这个问题,您需要知道EditValue方法有一个context参数,它是ITypeDescriptorContext类型,并且有一个Instance属性,它是您正在编辑的属性的所有者对象。 Having the owner (the Form) we know the type of the form and therefore we know the generic parameter type and therefore we can create our generic editor form.拥有所有者(表单),我们知道表单的类型,因此我们知道通用参数类型,因此我们可以创建我们的通用编辑器表单。

Step By Step Example分步示例

Above fact is the key point for the answer, but to solve the problem, you need to apply some other tricks as well.以上事实是答案的关键点,但要解决问题,您还需要应用一些其他技巧。 For example you should get a generic type and create an instance of it using reflection.例如,您应该获得一个泛型类型并使用反射创建它的一个实例。

Here I put a project containing the whole source code of the example:这里我放了一个项目,其中包含示例的整个源代码:

Here are steps of the example which creates a custom model UI Type Editor to show a list of properties of T when you are editing a specific property of a form which is derived from MyBaseForm<T> .以下是示例的步骤,该示例创建自定义模型 UI 类型编辑器,以在您编辑从MyBaseForm<T>派生的表单的特定属性时显示T的属性列表。

Generic Base Form通用基础表格

It's the base form for other forms which contains SomeProperty , the property which you want to edit using a custom editor.它是包含SomeProperty其他表单的基本表单,您要使用自定义编辑器编辑该属性。

Add a MyGenericType property to the class which returns typeof(T) , the generic type of the form: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); } }
}

Derived Form派生形式

It's a sample derived form which is derived from the MyBaseForm<T> .它是派生自MyBaseForm<T>的示例派生形式。 We will edit SomeProperty of an instance of this class.我们将编辑此类实例的SomeProperty

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

Sample Model示例模型

It's a sample model which we are going to show its properties in the custom editor window.这是一个示例模型,我们将在自定义编辑器窗口中显示其属性。

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

Editor Form编辑表格

It's the form which UITypeEditor will show.这是UITypeEditor将显示的表单。 In the form, we fill comoBox1 with field names of the generic argument.在表单中,我们用通用参数的字段名称填充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 Type Editor UI 类型编辑器

When calling EditValue method of the UITypeEditor , the context parameter is of type System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry which has a Component property which its value is the instance of the form which you are editing, so we know the type of the form and therefore we know the generic parameter type and therefore we can create our generic editor form and use it.调用UITypeEditor EditValue方法时, context参数的类型为System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry ,它有一个Component属性,其值是您正在编辑的表单的实例,因此我们知道表单的类型因此我们知道通用参数类型,因此我们可以创建我们的通用编辑器表单并使用它。

public class MyUITypeEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context,
        IServiceProvider provider, object value)
    {
        var svc = provider.GetService(typeof(IWindowsFormsEditorService))
            as IWindowsFormsEditorService;
        var myGenericTypeProperty = context.Instance.GetType()
            .GetProperty("MyGenericType");
        var genericArgument = (Type)myGenericTypeProperty.GetValue(context.Instance);
        var editorFormType = typeof(MyEditorForm<>);
        var genericArguments = new[] { genericArgument };
        var editorFormInstance = editorFormType.MakeGenericType(genericArguments);
        if (svc != null)
        {
            using (var f = (Form)Activator.CreateInstance(editorFormInstance))
                if (svc.ShowDialog(f) == DialogResult.OK)
                    return ((dynamic)f).SelectedProperty;
        }
        else
        {
            using (var f = (Form)Activator.CreateInstance(editorFormInstance))
                if (f.ShowDialog() == DialogResult.OK)
                    return ((dynamic)f).SelectedProperty;
        }
        return base.EditValue(context, provider, value);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何创建打开表单的自定义PropertyGrid编辑器项? - How to create custom PropertyGrid editor item which opens a form? 如何创建进行异步调用的自定义 PropertyGrid 编辑器? - How to create a custom PropertyGrid editor that makes async calls? 如何使用 C# 中的另一个(嵌套)编辑器为扩展 WPF 工具包 PropertyGrid 创建自定义属性编辑器? - How to create a custom property editor for Extended WPF Toolkit PropertyGrid with another (nested) editor in C#? PropertyGrid数组编辑器的自定义视图 - Custom view for PropertyGrid array editor 如何为PropertyGrid的自定义属性编辑器添加对多对象编辑的支持? - How to add support of multiobject edits for PropertyGrid's custom property editor? 如何在PropertyGrid自定义集合编辑器中的“添加”按钮下拉列表中自定义名称 - How to customize names in “Add” button dropdown in the PropertyGrid custom collection editor 如何创建将字符串限制为 n 个字符的 PropertyGrid 编辑器 - How to create a PropertyGrid editor that limits a string to n characters PropertyGrid(C#)中布尔属性的自定义编辑器 - Custom Editor for a Boolean Property in a PropertyGrid (C#) Xceed WPF propertyGrid自定义集合编辑器 - Xceed WPF propertyGrid Custom Collection editor 带有自定义编辑器的propertygrid对象,如滑块 - propertygrid object with custom editor like a slider
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM