Как создать пользовательскую форму редактора коллекции для использования с сеткой свойств?
Я пытаюсь включить элемент управления сеткой свойств с классом, который имеет список / коллекцию другого класса в качестве одного из свойств. Давайте назовем их классом A, и список будет содержать класс B для справки.
Я хотел включить форму, которая имела два списка. Поле со списком слева будет содержать список всех классов B в моей программе, которых в данный момент нет в списке справа. Список справа будет содержать все классы B, которые в настоящее время связаны с классом A. Я хочу, чтобы кнопки между ними перемещали элементы между двумя списками.
Это было бы легко спроектировать, но я не уверен, как именно настроить форму для использования в качестве редактора коллекции.
Может кто-то указать мне верное направление?
А также, как я могу настроить раскрывающийся список для свойства, которое содержит список идентификаторов, из которых можно выбрать, если кто-нибудь может указать мне направление для достижения этой цели.
2 ответа
Хорошо, я наконец смог отследить, как это сделать.
Я пытался создать кастом CollectionEditor.CollectionForm
что было близко к тому, что мне нужно было сделать, но это было не совсем верное направление.
Прежде всего, создайте обычную форму 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);
}
}
Ключевыми частями, на которые следует обратить внимание, являются функции GetEditStyle
а также EditValue
, Часть, ответственная за запуск Формы, созданной вами для редактирования вашей коллекции, находится в EditValue
переопределить функцию.
CForm
пользовательская форма редактора коллекции, которую я разработал в этом тесте для редактирования коллекции. Вам нужно получить IWindowsFormsEditorService
связано с IServiceProvider
и просто позвонить .ShowDialog(formVariable)
из IWindowsFormsEditorService
для того, чтобы показать форму, которую вы разработали для редактирования коллекции. Вы можете тогда catch
возвращенный DialogResult
значение из вашей формы и выполнять любые пользовательские обработки, которые вам требуются.
Я надеюсь, что это поможет кому-то, потому что мне потребовалось немало копать, чтобы определить правильный способ включить это.
Это отвечает на вопрос Брэндона. Я тоже долго и усердно искал, как на самом деле заменить редактор коллекции сетки свойств по умолчанию. Ответ Натана был окончательным решением. Брэндон, вот как я смог использовать решение Натана и использовать свой собственный редактор коллекций.
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://stackru.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;
}