2012-06-04 55 views
11

WPFで作業していて、ListViewを使用しています。アイテムが追加されたときにイベントを発生させる必要があります。私はこの試みている:event-fired-when-item-is-added-to-listviewが、最良の答え:WPF:アイテムがListViewに追加されたときにイベントを発生させる

var dependencyPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(ListView)); 
     if (dependencyPropertyDescriptor != null) 
     { 
       dependencyPropertyDescriptor.AddValueChanged(this, ItemsSourcePropertyChangedCallback); 
     } 

.....

private void ItemsSourcePropertyChangedCallback(object sender, EventArgs e) 
    { 
     RaiseItemsSourcePropertyChangedEvent(); 
    } 

をしかし、それは、コレクション全体が変更された場合にのみ動作しているようだ、私はこの記事を読んだことがありますlistBoxにのみ適用されます。私はListViewにコードを変更しようとしましたが、私はそれを行うことができませんでした。

私があなたを助けてくれることを願っています。前もって感謝します。

+0

あなたが投稿した質問への回答のコメントには、「私のコードを変更してより明確にする」があります。また、これはItemsControl(ListBoxまたはListView)で動作するはずです。 " - 何が特に問題なのですか? – Slugart

+0

@Slugartご回答いただきありがとうございます。問題は、' BeginInvoke'メソッドが宣言を"DispatcherPriority'が存在しないと言われました – Dante

答えて

37

これはWPFリストビューでのみ機能します。

いくつかの研究の後、私は私の質問への答えを発見したと、それは本当に簡単です:追加、移動、交換してください:

public MyControl() 
{ 
    InitializeComponent(); 
    ((INotifyCollectionChanged)listView.Items).CollectionChanged += ListView_CollectionChanged; 
} 

private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)  
{ 
    if (e.Action == NotifyCollectionChangedAction.Add) 
    { 
     // scroll the new item into view 
     listView.ScrollIntoView(e.NewItems[0]); 
    } 
} 

は実際には、NotifyCollectionChangedAction列挙型は、あなたのプログラムのような変更についてお知らせすることができます、削除とリセット。

+1

これは私のためには機能しません。タイプ 'ListViewItemCollection'のオブジェクトを 'System.Collections.Specialized.INotifyCollectionChanged'にキャストできません。 –

+1

好奇心が強い人は、 'ListView。Items'は 'ItemsCollection'型です。これは、 'INotifyCollectionChanged'を実装している' CollectionView'を継承しています。 MSDNを見ると、.NET 3.0 - 4.6ではこれが当てはまりました。 @Arvo 'ListViewItemCollection'は' IList、ICollection、IEnumerable'だけを実装し、何も継承しないので例外です。 –

+0

WPFリストボックスでも機能します。観測可能なコレクションがバインドされている場合、最初のオカレンスは[ビュー]に表示されます。したがって、同じ値が複数回発生する可能性がある場合は、1つのプロパティを持つクラス(observablecollection )をバインドし、それに応じてDisplayMemberPathを設定します。 – dba

-1

注:このソリューションは、WinForms ListView用です。私の場合、私は2つの選択肢と道路の分岐点に来てしまったで

...

(1)リストビューのクラスを継承するカスタムListViewコントロールを作成します。次に、アイテムが追加、削除、またはListViewがクリアされたときに生成される新しいイベントを追加します。この道は本当に面倒だった。私のオリジナルのListViewを新しく作成したCustom ListViewコントロールで置き換える必要があるという大きな問題は他にありません。だから私はこれを渡した!


(2)すべてのでは削除、追加、または私はまたて、CollectionChangedイベントをシミュレートする別の関数を呼び出し、リストビューに明確なコール。

機能などの新しいイベントを作成...

private void myListViewControl_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    //The projects ListView has been changed 
    switch (e.Action) 
    { 
     case NotifyCollectionChangedAction.Add: 
      MessageBox.Show("An Item Has Been Added To The ListView!"); 
      break; 
     case NotifyCollectionChangedAction.Reset: 
      MessageBox.Show("The ListView Has Been Cleared!"); 
      break; 
    } 
} 

他の場所でのListViewに項目を追加...

ListViewItem lvi = new ListViewItem("ListViewItem 1"); 
lvi.SubItems.Add("My Subitem 1"); 
myListViewControl.Items.Add(lvi); 
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, lvi, lvi.Index)); 

クリアを他の場所でのListView ...

myListViewControl.Items.Clear(); 
myListViewControl_CollectionChanged(myListViewControl, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
+0

Danteのソリューションは、特にあなたの回避策が... INotifyCollectionChangedを含む場合、あなたにとってうまくいきません。 '((INotifyCollectionChanged)MyList.Items).CollectionChanged + = MyListChanged'が私のために働いていました。かっこを正しい場所に置いてもよろしいですか? –

+0

多分WPFと関係がありますが、私はそれを使用しません。私はWinFormsを使用しています。わかりませんが、私が知っているのは、すべての名前空間が占められており、すべての参照がそれらのオブジェクト/タイプで完璧に機能するということです。私は実際にあなたがlistView.ItemsのコレクションをINotifyCollectionChangedにキャストする方法を実際には得ていません(それはできないと言っているわけではありません)。他のすべてはその部分を除いてよさそうだ。私はあなたが私に言ったら何かを試して喜んでいる。しかし、それは私のVS 2010はノーと言っている! ;) –

+2

WinFormsとWPFはまったく異なる2つの獣です。 WinFormsの 'ListView'は** WPFの' ListView'とは何も関係ありません! WPFの 'ListViewItemCollection'は' INotifyCollectionChanged'を実装しています。 WPFの強力なデータバインディング機能により、リスト内の変更を検出し、自動的に*自動的に*すべてを最新の状態に保ちます。 WinFormsを残してWPFを試してみることを検討する必要があります - 一度それを掛けたら、あなたは振り返ることはありません! :) –

関連する問題