C # Winforms: PropertyGrid не обновляется при добавлении элемента в коллекцию - PullRequest
4 голосов
/ 10 июня 2010

У меня есть собственный класс, который можно редактировать с помощью PropertyGrid. В этом классе у меня есть пользовательский Collection (с пользовательскими PropertyDescriptor и TypeConverter).

Элементы могут быть добавлены или удалены из Collection с помощью редактора коллекций по умолчанию. Это все отлично работает. Но - после закрытия редактора коллекций PropertyGrid не обновляется. Когда я вручную вызываю Refresh() на PropertyGrid, изменения отражаются в PropertyGrid.

Как заставить PropertyGrid автоматически обновляться после закрытия редактора коллекций? Ранее я искал решение, в котором я должен был бы создать подкласс CollectionEditor (который я не могу найти).

Пожалуйста, помогите.

Ответы [ 5 ]

1 голос
/ 06 ноября 2015

Я использую этот базовый класс

public class CollectionEditorBase : CollectionEditor
{
    protected PropertyGrid ownerGrid;

    public CollectionEditorBase(Type type) : base(type) { }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        PropertyInfo ownerGridProperty = provider.GetType().GetProperty("OwnerGrid", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        ownerGrid = (PropertyGrid)ownerGridProperty.GetValue(provider);

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

    protected override CollectionForm CreateCollectionForm()
    {
        CollectionForm cf = base.CreateCollectionForm();
        cf.FormClosing += delegate(object sender, FormClosingEventArgs e)
        {
            ownerGrid.Refresh();

            if (CollectionEditorClosed != null)
                CollectionEditorClosed(this, value);
        };

        return cf;
    }
}

Тогда вы просто основываете свой редактор коллекций на этом. Он автоматически обновит сетку свойств при закрытии формы коллекции.

Имейте в виду, что это решение отражается во внутренних элементах сетки свойств и может быть нарушено в любое время, но я сделал это некоторое время без проблем

1 голос
/ 17 июня 2010

Вы также можете попробовать добавить атрибут NotifyParentProperty в коллекцию. Это сработало для меня в подобных ситуациях.

1 голос
/ 12 апреля 2011

Я получаю решение в этой ситуации. Необходимо извлечь из класса CollectionEditor и сделать собственный редактор следующим образом:

public class MeasuredParamEditor : CollectionEditor
{

    public static EventHandler CollectionChanged;

    public MeasuredParamEditor(Type type)
        : base(type)
    { }

    protected override string GetDisplayText(object value)
    {
        if (value is MeasuredParam)
        {
            MeasuredParam param = (MeasuredParam)value;
            return string.Format("{0}: {1}", param.Name, param.Value);
        }
        else return base.GetDisplayText(value);
    }

    protected override CollectionForm CreateCollectionForm()
    {
        CollectionForm collectionForm = base.CreateCollectionForm();
        Form frm = collectionForm as Form;
        if (frm != null)
        {
            // Get OK button of the Collection Editor...
            Button button = frm.AcceptButton as Button;
            // Handle click event of the button
            button.Click += new EventHandler(OnCollectionChanged);
        }
        return collectionForm;
    }

    void OnCollectionChanged(object sender, EventArgs e)
    {
        if (CollectionChanged != null)
        {
            CollectionChanged(sender, e);
        }
    }
}

В основной форме я подписываюсь на статическое событие моего пользовательского редактора.

    private void MainForm_Load(object sender, EventArgs e)
    {
            MeasuredParamEditor.CollectionChanged += new EventHandler(OnMeasuredParamsChanged); 
    }

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        MeasuredParamEditor.CollectionChanged -= new EventHandler(OnMeasuredParamsChanged);

    }

    void OnMeasuredParamsChanged(object sender, EventArgs e)
    {
        this.myPropGrid.Refresh();
    }

С уважением, Артем

1 голос
/ 10 июня 2010

RefreshPropertiesAttribute Class

Указывает, что сетка свойств должен обновить, когда связанный значение свойства изменяется. Этот класс не может быть унаследовано.

Вставлено с http://msdn.microsoft.com/en-us/library/system.componentmodel.refreshpropertiesattribute.aspx

Добавление атрибута с дескриптором

        Public Overrides ReadOnly Property Attributes() As System.ComponentModel.AttributeCollection
            Get
                Return New AttributeCollection(New Attribute() {RefreshPropertiesAttribute.Repaint})
            End Get
        End Property

Пошаговое руководство. Отладка пользовательских элементов управления Windows Forms во время разработки в http://msdn.microsoft.com/en-us/library/5ytx0z24.aspx

0 голосов
/ 19 ноября 2016

идеальное решение

using System;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Drawing.Design;
using System.Collections;
using System.ComponentModel;

namespace ppgExpandableList
{
    public class ExpandableListEditor : CollectionEditor
    {
        public ExpandableListEditor(Type type) : base(type){}
        public override object EditValue(ITypeDescriptorContext context,
            System.IServiceProvider provider, object value)
        {
            object editedValue = base.EditValue(context, provider, value);

            IList tmpList = (IList)editedValue;
            object tmpValue = Activator.CreateInstance(value.GetType());
            IList editedList = (IList)tmpValue;

            foreach (object item in tmpList)
            {
                editedList.Add(item);
            }

            return editedList;
        }

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
    }
}
...