Предварительный просмотр UserControl не обновляется при удалении существующих элементов в CollectionEditor - PullRequest
0 голосов
/ 22 июля 2009

Я столкнулся с этой проблемой с по умолчанию CollectionEditor.

При добавлении элементов в редакторе коллекции, я отобразить элементы в виде прямоугольника на пользовательском элементе управления. Но когда я удалить элементы, которые присутствовали уже предварительный просмотр не обновляется до тех пор пока я нажмите на кнопку OK или кнопку Добавить.

Я представил код для того же ниже.

Шаги для производства:

  1. Добавление элемента управления из.
  2. Измените свойство коллекции элемента управления путем открытия CollectionEditor и добавления (скажем 3. пунктов. (U см элементы добавляться в контроле). Предварительный просмотр обновляется красиво.
  3. Теперь нажмите на кнопку OK.
  4. Re-открыть CollectionEditor и попробуйте удалить существующий элемент. Я ожидаю, что пункты будут удалены в окне предварительного просмотра. Но удаленные элементы остаются на контроле, пока не нажать на кнопку «Добавить» или кнопку «OK». (

Является ли это ошибка в классе CollectionEditor?

Исходный код:

TestCollectionClass.cs

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
using System.Globalization;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Drawing;

namespace TestCollectionEditor
{
    using T = TestComponent;

    [
        Editor("", typeof(UITypeEditor)),
        ListBindable(false)
    ]
    public class TestCollectionClass : IList, ICollection, IEnumerable
    {
        private IList _list;
        private Size _renderFrame;

        public delegate void CollectionChangeEventHandler(object sender, EventArgs e);
        public event CollectionChangeEventHandler _onCollectionChanged;
        public event CollectionChangeEventHandler CollectionChanged
        {
            add
            {
                lock (this)
                {
                    _onCollectionChanged += value;
                }
            }
            remove
            {
                lock (this)
                {
                    _onCollectionChanged -= value;
                }
            }
        }

        protected virtual void OnCollectionChanged(EventArgs e)
        {
            if (_onCollectionChanged != null)
            {
                _onCollectionChanged(this, e);
            }
        }

        public TestCollectionClass(Size size)
        {
            _list = new ArrayList();
            _renderFrame = size;
        }

        public TestCollectionClass(T[] item)
            : this(new Size(100, 100))
        {
            AddRange(item);
        }

        public TestCollectionClass(TestCollectionClass item)
            : this(new Size(100, 100))
        {
            AddRange(item);
        }

        public override string ToString()
        {
            return String.Format(CultureInfo.CurrentCulture, "{0}: Count={1}", GetType().Name, Count);
        }

        public T this[int index]
        {
            get { return (T)_list[index]; }
            set
            {
                _list[index] = value;
            }
        }

        object IList.this[int index]
        {
            get { return this[index]; }
            set
            {
                T item = value as T;
                if (item == null)
                    throw GetInvalidTypeException(value);

                this[index] = item;
            }
        }

        public int Add(T item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            int i = _list.Add(item);
            OnCollectionChanged(new EventArgs());
            return i;
        }

        int IList.Add(object item)
        {
            T value = item as T;
            if (value == null)
                throw GetInvalidTypeException(item);

            return Add(value);
        }

        public void AddRange(T[] item)
        {
            if (item == null)
                throw new ArgumentNullException("item");

            foreach (T current in item)
                Add(current);
        }

        public void AddRange(TestCollectionClass item)
        {
            if (item == null)
                throw new ArgumentNullException("item");

            foreach (T current in item)
                Add(current);
        }

        public void Clear()
        {
            _list.Clear();
            OnCollectionChanged(new EventArgs());
        }

        public int Count
        {
            get { return _list.Count; }
        }

        public bool Contains(T item)
        {
            if (item == null)
            {
                return false;
            }

            return _list.Contains(item);
        }

        bool IList.Contains(object item)
        {
            T value = item as T;
            if (value == null)
                throw GetInvalidTypeException(item);

            return Contains(value);
        }

        public void CopyTo(T[] array, int index)
        {
            ICollection collection = this as ICollection;
            collection.CopyTo(array, index);
        }

        void ICollection.CopyTo(System.Array array, int index)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }

            _list.CopyTo(array, index);
        }

        public int IndexOf(T item)
        {
            if (item == null)
            {
                return -1;
            }

            return _list.IndexOf(item);
        }

        int IList.IndexOf(object item)
        {
            T value = item as T;
            if (value == null)
                throw GetInvalidTypeException(item);

            return IndexOf(value);
        }

        public void Insert(int index, T item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            _list.Insert(index, item);
            OnCollectionChanged(new EventArgs());
        }

        void IList.Insert(int index, object item)
        {
            T value = item as T;
            if (value == null)
                throw GetInvalidTypeException(item);

            Insert(index, value);
        }

        bool ICollection.IsSynchronized
        {
            get { return IsSynchronized; }
        }

        protected bool IsSynchronized
        {
            get { return _list.IsSynchronized; }
        }

        bool IList.IsFixedSize
        {
            get { return IsFixedSize; }
        }

        protected bool IsFixedSize
        {
            get { return _list.IsFixedSize; }
        }

        bool IList.IsReadOnly
        {
            get { return IsReadOnly; }
        }

        protected bool IsReadOnly
        {
            get { return _list.IsReadOnly; }
        }

        object ICollection.SyncRoot
        {
            get { return SyncRoot; }
        }

        protected object SyncRoot
        {
            get { return _list.SyncRoot; }
        }

        public IEnumerator GetEnumerator()
        {
            return _list.GetEnumerator();
        }

        public void Remove(T item)
        {
            if (item != null)
            {
                _list.Remove(item);
                OnCollectionChanged(new EventArgs());
            }
        }

        void IList.Remove(object item)
        {
            T value = item as T;
            if (value == null)
                throw GetInvalidTypeException(item);

            Remove(value);
        }

        public void RemoveAt(int index)
        {
            _list.RemoveAt(index);
            OnCollectionChanged(new EventArgs());
        }

        private static Exception GetInvalidTypeException(object obj)
        {
            return new NotSupportedException();
        }
    }
}

TestComponent.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Drawing;

namespace TestCollectionEditor
{    
    public partial class TestComponent : Component
    {
        public TestComponent()
        {
            InitializeComponent();
            _position = new Point(random.Next(), random.Next());
            _size = new Size(100, 100);
            _color = Color.FromArgb(random.Next()%255,random.Next()%255,random.Next()%255);
        }

        public TestComponent(IContainer container)
        {
            container.Add(this);
            _position = new Point(random.Next(), random.Next());
            _size = new Size(10, 10);

            InitializeComponent();
        }

        private Point _position;
        private Size _size;
        private Color _color;
        private static Random random = new Random();

        public Color Color
        {
            get
            {
                return _color;
            }
        }

        public Point Position
        {
            get
            {
                return _position;
            }
        }

        public Size Size
        {
            get
            {
                return _size;
            }
        }

        public void Draw(Graphics g, Size renderFrame)
        {
            Point newPosition = new Point(Position.X % renderFrame.Width, Position.Y % renderFrame.Height);
            g.FillRectangle(new SolidBrush(Color), new Rectangle(newPosition, Size));
        }

        private void InitializeComponent()
        {
        }
    }
}

CollectionEditorTestUserControl.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TestCollectionEditor
{
    public partial class CollectionEditorTestUserControl : UserControl
    {
        public CollectionEditorTestUserControl()
        {
            //this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            _collection = new TestCollectionClass(Size);
            _collection.CollectionChanged += new TestCollectionClass.CollectionChangeEventHandler(OnCollectionChanged);
            InitializeComponent();
        }

        private void OnCollectionChanged(object sender, EventArgs e)
        {
            Invalidate();
        }

        private TestCollectionClass _collection;
        public TestCollectionClass Collection
        {
            get
            {
                return _collection;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            for (int i = 0; i < _collection.Count; i++ )
            {
                TestComponent c = _collection[i];
                c.Draw(e.Graphics, Size);
            }
        }
    }
}

1 Ответ

0 голосов
/ 22 июля 2009

Может быть ошибка, особенно если Add является динамическим, а Delete нет. Уведомление OnCollectionChanged, вероятно, является просто циклом «добавления новых элементов» без учета удалений. Вот почему добавленные элементы работают.

Не глядя на реализацию, я ожидаю, что редактируемая коллекция является копией той, что находится в элементе управления. При нажатии кнопки «ОК / Добавить» измененная коллекция копируется обратно в вашу собственность. Это когда удаления вступают в силу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...