Как определить, что свойство коллекции UserControl изменилось во время разработки? - PullRequest
1 голос
/ 21 июня 2011

У меня есть UserControl, который имеет свойство коллекции. Часть моих требований заключается в том, что графический интерфейс элемента управления изменяется в DesignMode в зависимости от содержимого коллекции. Например, ListBox.

Мой код выглядит так (переопределение Add - просто эксперимент):

public partial class MyControl: UserControl
{
    public class StringCollection : List<string>
    {
        public new void Add(string item)
        {
            Console.Beep();
            base.Add(item);
        }
    }       

    [Category("Data")]
    [Description("The items to be displayed in the Control.")] 
    [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", typeof(System.Drawing.Design.UITypeEditor))]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public StringCollection Items
    {
        get
        {
            return mItems;
        }
    }

Все работает нормально, за исключением того, что во время разработки выясняется, что коллекция была изменена с помощью StringCollectionEditor. Я получаю "Beeps" при создании элемента управления, и если я добавляю в коллекцию из кода.

Я знаю, что это можно сделать, потому что ListBox делает это. У кого-нибудь есть идеи как? Заранее спасибо.

1 Ответ

2 голосов
/ 21 июня 2011

Это проблема с ключевым словом new , оно не может волшебным образом сделать методы виртуальными. StringCollectionEditor будет вызывать IList.Add () для добавления элемента. Это вызовет List <>. Add (), а не вашу версию. Вы должны отказаться от List <> и реализовать свой собственный класс коллекции, который наследуется от IList. Это в основном скучная работа, вы используете List <> для ее реализации. Как это:

    class StringCollection : System.Collections.IList {
        private List<object> impl = new List<object>();
        public int Add(object value) {
            Console.Beep();
            impl.Add(value);
            return Count;
        }

        public void Clear() {
            impl.Clear();
        }

        // etc...
    }

Обратите внимание, как ListBox сделал это тоже, он использует ObjectCollection. Может быть, вы можете использовать это также. Помните, что Winforms были созданы до того, как стали доступны дженерики.

...