0


0

デフォルトのCollectionEditorでこの問題に直面しています。

コレクションエディタにアイテムを追加すると、そのアイテムはユーザーコントロール上の四角形として表示されます。 しかし、すでに存在していたアイテムを削除してもプレビューが更新されず、[OK]または[追加]ボタンをクリックするまで更新されません。

私は以下のコードを提供しました。

生成する手順

  1. fromにコントロールを追加します。

  2. CollectionEditorを開いて追加することで、コントロールのCollectionプロパティを編集します(例3)。 アイテム (U項目がコントロールに追加されるのを参照してください)。 プレビューはうまく更新されます。

  3. OKボタンをクリックしてください。

  4. CollectionEditorを再度開き、既存のアイテムを削除してみてください。 プレビューでアイテムが削除されると思います。 しかし、削除した項目は、[追加]ボタンまたは[OK]ボタンをクリックするまでコントロールに残ります。 :(

これはCollectionEditorクラスのバグですか?

ソースコード:

TestCollectionClass.cs

システムを使用する。 System.Collectionsを使用します。 System.ComponentModelを使用します。 System.Drawing.Designを使用する。 System.Globalizationを使用します。 System.Security.Permissionsを使用します。 System.Windows.Formsを使用します。 System.Drawingを使用します。

namespace TestCollectionEditor {using T = TestComponent;

[Editor( ""、typeof(UITypeEditor))、ListBindable(false)]パブリッククラスTestCollectionClass:IList、ICollection、IEnumerable {private IList _list;}プライベートサイズ_renderFrame;

パブリックデリゲートvoid CollectionChangeEventHandler(オブジェクトセンダ、EventArgs e);パブリックイベントCollectionChangeEventHandler _onCollectionChanged;パブリックイベントCollectionChangeEventHandler CollectionChanged {add {lock(this){_onCollectionChanged = value;} {{lock(this){_onCollectionChanged  -  = value;}}を削除します。 }}}

OnCollectionChanged(EventArgs e){if(_onCollectionChanged!= null){_onCollectionChanged(this、e); }}

public TestCollectionClass(サイズsize){_list = new ArrayList(); _renderFrame = size; }

public TestCollectionClass(T [] item):これ(新しいサイズ(100、100)){AddRange(item); }

public TestCollectionClass(TestCollectionClass item):これ(新しいサイズ(100、100)){AddRange(item); }

パブリックオーバーライド文字列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;} }}

オブジェクトIList.this [int index] {get {return this [index];} {T item = valueをTとします。 if(item == null)はGetInvalidTypeException(value)をスローします。

this [index] = item; }}

public int Add(T item){if(item == null){新しいArgumentNullException( "item")をスローします。 }

int i = _list.Add(item); OnCollectionChanged(new EventArgs()); iを返します。 }

int IList.Add(object item){T値= item as T; if(value == null)はGetInvalidTypeException(item)をスローします。

Add(value)を返します。 }

public void AddRange(T [] item){if(item == null)は新しいArgumentNullException( "item")をスローします。

foreach(T current in item)加算(current); }

public void AddRange(TestCollectionClass item){if(item == null)新しいArgumentNullException( "item");

foreach(T current in item)加算(current); }

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

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

public bool(T item){if(item == null){falseを返します。 }

_list.Contains(item)を返します。 }

bool IList.Contains(object item){T値= item as T; if(value == null)はGetInvalidTypeException(item)をスローします。

(値)を含みます。 }

public void CopyTo(T [] array、int index){ICollectionコレクション= ICollectionとしてのthis; collection.CopyTo(配列、インデックス); }

void ICollection.CopyTo(System.Array array、int index){if(array == null){新しいArgumentNullException( "array"); }

_list.CopyTo(配列、インデックス); }

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

_list.IndexOf(item)を返します。 }

int IList.IndexOf(object item){T値= item as T; if(value == null)はGetInvalidTypeException(item)をスローします。

IndexOf(値)を返します。 }

public void Insert(int index、T item){if(item == null){新しいArgumentNullException( "item")をスローします。 }

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

void IList.Insert(int index、object item){T値= item as T; if(value == null)はGetInvalidTypeException(item)をスローします。

挿入(インデックス、値)。 }

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

オブジェクトICollection.SyncRoot {get {return SyncRoot; }}

保護オブジェクトSyncRoot {get {return _list.SyncRoot;}} }}

パブリックIEnumerator GetEnumerator(){return _list.GetEnumerator();} }

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

void IList.Remove(object item){T値= item as T; if(value == null)はGetInvalidTypeException(item)をスローします。

削除(値)。 }

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

プライベートな静的な例外GetInvalidTypeException(object obj){新しいNotSupportedException()を返す。 }}}

TestComponent.cs

システムを使用する。 System.Collections.Genericを使用します。 System.ComponentModelを使用します。 System.Diagnosticsを使用します。 System.Linqを使用します。 System.Textを使用します。 System.Drawingを使用します。

名前空間TestCollectionEditor {public部分クラス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.Add(this); _position = new Point(random.Next()、random.Next()); _size = new Size(10、10);

InitializeComponent(); }

private Point _position;プライベートサイズプライベートカラー_color; private staticランダム乱数= new Random();

パブリックカラーColor {get {return _color;} }}

パブリックポイント位置{get {return _position;} }}

publicサイズ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(カラー)、new Rectangle(newPosition、Size)); }

private void InitializeComponent(){}}}

CollectionEditorTestUserControl.cs

システムを使用する。 System.Collections.Genericを使用します。 System.ComponentModelを使用します。 System.Drawingを使用します。 System.Dataを使用します。 System.Linqを使用します。 System.Textを使用します。 System.Windows.Formsを使用します。

namespace TestCollectionEditor {public部分クラスCollectionEditorTestUserControl:UserControl {public CollectionEditorTestUserControl(){// {this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; _collection = new TestCollectionClass(サイズ); _collection.CollectionChanged = new TestCollectionClass.CollectionChangeEventHandler(OnCollectionChanged); InitializeComponent(); }

private void OnCollectionChanged(オブジェクトセンダ、EventArgs e){Invalidate(); }

プライベートTestCollectionClass _collection。 public TestCollectionClassコレクション{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 Answer


0


特にAddが動的でDeleteが動的ではない場合、バグになるかもしれません。 OnCollectionChanged通知は、削除を考慮に入れない、おそらく単に「新しい項目を追加する」ループです。 追加アイテムが機能するのはそのためです。

実装を見なくても、編集中のコレクションはコントロール内のコレクションのコピーであることが期待できます。 [OK] / [追加]をクリックすると、変更されたコレクションがあなたの施設にコピーされます。 削除が有効になるのはこのときです。