在 CollectionEditor 中删除现有项目时,UserControl 预览不会更新

发布于 2024-07-27 04:58:12 字数 10345 浏览 10 评论 0原文

我在使用默认 CollectionEditor 时遇到了这个问题。

当我将项目添加到集合编辑器时,我将这些项目显示为用户控件上的矩形。 但是,当我删除已经存在的项目时,预览不会更新,直到我单击“确定”或“添加”按钮。

我在下面提供了相同的代码。

制作步骤:

  1. 在from中添加一个控件。
  2. 通过打开 CollectionEditor 并添加(例如 3. 项目)来编辑控件的 Collection 属性。(您会看到项目被添加到控件中)。预览得到很好的更新。
  3. 现在单击“确定”按钮。
  4. 重新打开 CollectionEditor 并尝试删除我希望在预览中删除这些项目,但在我单击“添加”按钮或“确定”按钮之前,删除的项目仍然保留在控件上:(

是 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);
            }
        }
    }
}

I am facing this problem with default CollectionEditor.

When I add items to the collection editor, I display the items as a rectangle on the user control. But when I delete the items that were present already the preview does not gets updated untill i click on OK or Add button.

I have provided the code for the same below.

Steps to produce:

  1. Add a control to from.
  2. Edit the Collection property of the control by opening CollectionEditor and adding (say 3. items. (U see the items getting added to the control). The preview gets updated nicely.
  3. Now click on OK button.
  4. Re-open the CollectionEditor and try deleting the existing item. I would expect the items being deleted in the preview. But the deleted items remains on the control till I click on 'Add' button or 'OK' button. :(

Is this is a bug in the CollectionEditor class?

Source Code:

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);
            }
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

相思碎 2024-08-03 04:58:12

可能是一个错误,尤其是当“添加”是动态的而“删除”不是动态时。 OnCollectionChanged 通知可能只是一个“添加新项目”循环,而不考虑删除。 这就是添加项目起作用的原因。

在不查看实现的情况下,我希望您正在编辑的集合是控件中集合的副本。 单击“确定/添加”后,修改后的集合将复制回您的属性。 此时删除生效。

Might be a bug, especially if Add is dynamic and Delete isn't. The OnCollectionChanged notification is probably just a "add new items" loop, without taking deletes into account. So that is why added items work.

Without looking at the implementation I'd expect that the collection you are editing is a copy of the one in the control. When OK/Add is clicked, then the modified collection is copied back to your property. This is when the deletes take effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文