在 CollectionEditor 中删除现有项目时,UserControl 预览不会更新
我在使用默认 CollectionEditor 时遇到了这个问题。
当我将项目添加到集合编辑器时,我将这些项目显示为用户控件上的矩形。 但是,当我删除已经存在的项目时,预览不会更新,直到我单击“确定”或“添加”按钮。
我在下面提供了相同的代码。
制作步骤:
- 在from中添加一个控件。
- 通过打开 CollectionEditor 并添加(例如 3. 项目)来编辑控件的 Collection 属性。(您会看到项目被添加到控件中)。预览得到很好的更新。
- 现在单击“确定”按钮。
- 重新打开 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:
- Add a control to from.
- 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.
- Now click on OK button.
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可能是一个错误,尤其是当“添加”是动态的而“删除”不是动态时。 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.