【问题标题】:How do you create a custom collection editor form for use with the property grid?如何创建自定义集合编辑器表单以与属性网格一起使用?
【发布时间】:2011-11-23 17:03:05
【问题描述】:

我正在尝试将属性网格控件与具有另一个类的列表/集合作为属性之一的类合并。让我们称它们为 A 类,列表将包含 B 类以供参考。

我想合并一个有两个列表框的表单。左侧的列表框将包含我的程序中当前不在右侧列表中的所有 B 类的列表。右侧的列表将包含当前与 A 类关联的所有 B 类。我想要在两个列表之间移动项目的按钮。

这很容易设计,但我不确定如何设置表单以用作集合编辑器。

谁能指出我正确的方向?

另外,如果有人能指出我完成此任务的方向,我该如何设置一个包含 id 列表的属性的下拉列表以供选择。

【问题讨论】:

  • 任何想法如何将表单设置为集合编辑器表单?

标签: c# .net propertygrid collectioneditor


【解决方案1】:

好的,我终于知道如何做到这一点了。

我试图创建一个自定义的CollectionEditor.CollectionForm,这与我需要做的很接近,但它的方向并不完全正确。

首先,创建一个包含用于编辑集合的 GUI 的常规 Windows 窗体。然后只需在表单中包含返回 DialogResult 的按钮/按钮。

现在完成我正在寻找的关键不是CollectionEditor.CollectionForm,因为我认为这是正确的方法,而是UITypeEditor

所以,我创建了一个继承自 UITypeEditor 的类。然后你就简单地把它充实起来:

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);
    }
}

需要注意的关键部分是函数GetEditStyleEditValue。负责触发您为编辑集合而创建的表单的部分位于 EditValue 覆盖函数中。

CForm 是我在本次测试中设计的自定义集合编辑器表单,用于编辑集合。您需要获取与IServiceProvider 关联的IWindowsFormsEditorService 并简单地调用IWindowsFormsEditorService.ShowDialog(formVariable) 以显示您设计用于编辑集合的表单。然后,您可以 catch 从您的表单返回的 DialogResult 值并执行您需要的任何自定义处理。

我希望这对某人有所帮助,因为我花了很多时间来确定合并它的正确方法。

【讨论】:

  • 15 个月后,我发现您在这里的努力非常有用。谢谢!
  • 这非常适合我正在从事的快速而肮脏的玩具项目。
  • 2 年半后,这仍然帮助了我。虽然,我如何将现有的收藏放入创建的表单中!
  • 看起来不错,如何在自定义控件中使用它?
【解决方案2】:

这回答了布兰登的问题。我也对如何实际替换默认的 propertygrid 集合编辑器进行了长期而艰苦的搜索。内森的回答是最终的解决方案。 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;
        }   

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多