Как создать пользовательскую форму редактора коллекции для использования с сеткой свойств?

Я пытаюсь включить элемент управления сеткой свойств с классом, который имеет список / коллекцию другого класса в качестве одного из свойств. Давайте назовем их классом 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;
        }   
Другие вопросы по тегам