我正在尝试将属性网格控件与具有另一个类的列表/集合作为属性之一的类合并。 我们称它们为 A 类,列表将包含 B 类以供参考。
我想合并一个有两个列表框的表单。 左侧的列表框将包含我的程序中当前不在右侧列表中的所有 B 类的列表。 右侧的列表将包含当前与 A 类关联的所有 B 类。我想要中间的按钮在两个列表之间移动项目。
这很容易设计,但我不确定如何设置用作集合编辑器的表单。
有人能指出我正确的方向吗?
而且,如果有人能指出我完成此操作的方向,我该如何为包含 id 列表的属性设置下拉列表以供选择。
好吧,我终于找到了如何实现这一点。
CollectionEditor.CollectionForm
,它接近我需要做的事情,但这不是正确的方向。
首先,创建一个常规 Windows 窗体,其中包含用于编辑集合的 GUI。然后只需在表单中包含返回 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);
}
}
需要注意的关键部分是函数
GetEditStyle
和EditValue
。 负责触发您创建的用于编辑集合的表单的部分位于 EditValue
覆盖函数中。
CForm
是我在本次测试中设计的自定义集合编辑器表单,用于编辑集合。 您需要获取与 IWindowsFormsEditorService
关联的 IServiceProvider
,并简单地调用 .ShowDialog(formVariable)
的 IWindowsFormsEditorService
,以便显示您设计用于编辑集合的表单。 然后,您可以 catch
从表单中返回 DialogResult
值,并执行您需要的任何自定义处理。
我希望这对某人有帮助,因为我花了相当多的时间来确定合并此内容的正确方法。
这回答了布兰登的问题。我也花了很长时间努力寻找如何实际替换默认的 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;
}