简体   繁体   English

如何创建自定义集合编辑器表单以与属性网格一起使用?

[英]How do you create a custom collection editor form for use with the property grid?

I am trying to incorporate a property grid control with a class that has a list/collection of another class as one of the properties. 我试图将属性网格控件与一个类相结合,该类具有另一个类的列表/集合作为其中一个属性。 Lets call them class A and the list would be containing class B for reference. 让我们称它们为A类,列表将包含B类以供参考。

I was wanting to incorporate a form that had two list boxes. 我想要合并一个有两个列表框的表单。 The list box on the left would contain a list of all of class B's in my program that are not currently in the list on the right. 左侧的列表框将包含我的程序中当前不在右侧列表中的所有B类的列表。 The list on the right would contain all of the class B's that are currently associated with class A. I want buttons in between to move items between the two lists. 右边的列表将包含当前与A类关联的所有B类。我希望两者之间的按钮在两个列表之间移动项目。

This would be easy to design, but I'm not sure exactly how to set up the form to be used as the collection editor. 这很容易设计,但我不确定如何设置表单以用作集合编辑器。

Can anyone point me in the right direction? 谁能指出我正确的方向?

And also, how can I go about having setting up a drop down for a property that contains a list of id's to select from if anyone could point me in the direction for accomplishing this as well. 而且,我如何设置一个包含可供选择的ID列表的属性的下拉列表,如果有人可以指出我的方向来完成这个。

Okay, I was finally able to track down how to accomplish this. 好的,我终于能够找到如何实现这一目标。

I was attempting to create a custom CollectionEditor.CollectionForm which was close to what I needed to do, but it wasn't quite the right direction. 我试图创建一个接近我需要做的自定义CollectionEditor.CollectionForm ,但它不是正确的方向。

First of all, create a regular Windows Form which includes your GUI for editing your collection. 首先,创建一个常规的Windows窗体,其中包含用于编辑集合的GUI。 Then just include button/buttons which return a DialogResult in the Form. 然后只包括在窗体中返回DialogResult的按钮/按钮。

Now the key to accomplishing what I was looking for is not a CollectionEditor.CollectionForm as I had thought would be the correct approach, but rather a UITypeEditor . 现在,完成我正在寻找的东西的关键不是CollectionEditor.CollectionForm因为我认为这是正确的方法,而是UITypeEditor

So, I created a class that inherited from the UITypeEditor. 所以,我创建了一个继承自UITypeEditor的类。 Then you simply flesh it out as such: 然后你就这样简单地充实它:

public class CustomCollectionModalEditor: UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        if (context ==null || context.Instance == null)                
            return base.GetEditStyle(context);

        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService editorService;

        if (context == null || context.Instance == null || provider == null)
            return value;

        editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

        CForm CollectionEditor = new CForm();

        if (editorService.ShowDialog(CollectionEditor) == System.Windows.Forms.DialogResult.OK)
            return CollectionEditor.Programmed;

        return value;
        //return base.EditValue(context, provider, value);
    }
}

The key parts to take note of, are the functions GetEditStyle and EditValue . 需要注意的关键部分是函数GetEditStyleEditValue The part responsible for firing-off the Form you created to edit your collection, is in the EditValue override function. 在编辑集合时,负责触发您创建的表单的部分位于EditValue覆盖功能中。

CForm is the custom collection editor form I designed in this test to edit the collection. CForm是我在此测试中设计的自定义集合编辑器表单,用于编辑集合。 You need to fetch the IWindowsFormsEditorService associated with the IServiceProvider and simply call the .ShowDialog(formVariable) of the IWindowsFormsEditorService in order to show the form you designed to edit the collection. 你需要获取IWindowsFormsEditorService与相关IServiceProvider和简单的调用.ShowDialog(formVariable)中的IWindowsFormsEditorService为了显示你设计的编辑集合的形式。 You can then catch the returned DialogResult value from your Form and perform any custom handling that you require. 然后,您可以从表单中catch返回的DialogResult值,并执行所需的任何自定义处理。

I hope this helps someone out as it took me quite a bit of digging to determine the right way to incorporate this. 我希望这可以帮助别人,因为我花了很多时间来确定合适的方法。

This answers Brandon's question. 这回答了布兰登的问题。 I too searched long and hard on how to actually replace the default propertygrid collection editor. 我也经常搜索如何实际替换默认的propertygrid集合编辑器。 Nathan's answer was the final solution. 内森的答案是最终解决方案。 Brandon here is how I was able to use Nathan's solution and use my own collection editor. Brandon在这里是我如何能够使用Nathan的解决方案并使用我自己的收藏编辑器。

using Swfd = System.Windows.Forms.Design;
using Scm = System.ComponentModel; 
using Sdd = System.Drawing.Design;
public class CustomCollectionModalEditor : Sdd.UITypeEditor
{
public override Sdd.UITypeEditorEditStyle GetEditStyle(Scm.ITypeDescriptorContext context)
{
    if (context == null || context.Instance == null)
    return base.GetEditStyle(context);

    return Sdd.UITypeEditorEditStyle.Modal;
}

public override object EditValue(Scm.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
    Swfd.IWindowsFormsEditorService editorService;

    if (context == null || context.Instance == null || provider == null)
    return value;

    editorService = (Swfd.IWindowsFormsEditorService)provider.GetService(typeof(Swfd.IWindowsFormsEditorService));

    //CForm CollectionEditor = new CForm();
    //---  Replaced the Collection from this post with mine which requires an argument that passes the collection
    Ccne.CustomCollection editgcp = new Ccne.CustomCollection();  // Ccne.CustomCollection is my collection
    editgcp = MYGCPS;  // MYGCPS is the actual instance to be edited

    Gcp_Editor.GcpEditorMain CollectionEditor = new Gcp_Editor.GcpEditorMain(editgcp);  // call my editor 

    if (editorService.ShowDialog(CollectionEditor) == System.Windows.Forms.DialogResult.OK)
    {
    MYGCPS = CollectionEditor.ReturnValue1; // update current instance of the collection with the returned edited collection
    THISPG.Refresh();  // calls a method which refreshes the property grid
    return value; // the replaces the statment in the post >> CollectionEditor.Programmed;
    }
    //---
    return value;

    //return base.EditValue(context, provider, value);
}
}


//---------- The propertygrid entry
private Ccne.CustomCollection gCPs; 

[Scm.Category("3 - Optional inputs to run gdal_translate")]
[PropertyOrder(133)]
[Scm.TypeConverter(typeof(Ccne.CustomCollectionConverter))]
[Scm.Editor(typeof(CustomCollectionModalEditor), typeof(Sdd.UITypeEditor))]
[Scm.Description("The Collection of the single or multiple Ground Control Points (Gcp)" +
" entered. \n Each gcp requires a Name, pixel, line, easting, " +
"northing, and optionally an elevation")]
[Scm.RefreshProperties(Scm.RefreshProperties.All)] // http://stackoverflow.com/questions/3120496/updating-a-propertygrid
[Scm.DisplayName("23 Collection of Gcp's")]
[Scm.ReadOnly(true)]                   // prevents values being changed without validation provided by form
public Ccne.CustomCollection GCPs
{
get { return gCPs; }
set { gCPs = value; }
}

//-------- important code from CollectionEditor i.e. > Gcp_Editor.GcpEditorMain(editgcp)
using Swf = System.Windows.Forms;
namespace Gcp_Editor
{
    public partial class GcpEditorMain : Swf.Form
    {
        public Ccne.CustomCollection ReturnValue1 { get; set; }
        ...
        public GcpEditorMain(Ccne.CustomCollection input1)
        {
                InitializeComponent();
                formcollection = input1;
        }
        ...
        private void OkayBtn_Click(object sender, EventArgs e)
        {
            this.DialogResult = Swf.DialogResult.OK;
            ReturnValue1 = formcollection;
            return;
        }   

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM