4

次のテストコードがあります。

private class SomeItem
    {
       public string Title{ get{ return "something"; } }
       public bool Completed { get { return false; } set { } }
    }

    private class SomeCollection : IEnumerable<SomeItem>, INotifyCollectionChanged
    {
        private IList<SomeItem> _items = new List<SomeItem>();
        public void Add(SomeItem item)
        {
            _items.Add(item);
            CollectionChanged(this, new 
             NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        #region IEnumerable<SomeItem> Members

        public IEnumerator<SomeItem> GetEnumerator()
        {
            return _items.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _items.GetEnumerator();
        }

        #endregion

        #region INotifyCollectionChanged Members

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        #endregion
    }

    private SomeCollection collection = new SomeCollection();

    private void Expander_Expanded(object sender, RoutedEventArgs e)
    {
        var expander = (Expander) sender;
        var list = expander.DataContext as ITaskList;
        var listBox = (ListBox)expander.Content;
        //list.Tasks.CollectionChanged += CollectionChanged;
        collection.Add(new SomeItem());
        collection.Add(new SomeItem());
        listBox.ItemsSource = collection;
    }

および XAML

<ListBox Name="taskListList" ItemsSource="{Binding}" BorderThickness="0" ItemContainerStyle="{StaticResource noSelectedStyle}" >
    <ListBox.ItemTemplate>
        <DataTemplate>
           <Expander Expanded="Expander_Expanded">
              <Expander.Header>
                <StackPanel Orientation="Horizontal">
                  <TextBlock Text="{Binding Name}" />
                  <TextBox KeyUp="TextBox_KeyUp" Width="200"/>
                  <Button Name="hide" Click="hide_Click">
                      <TextBlock Text="hide" />
                  </Button>
                </StackPanel>
               </Expander.Header>
                  <ListBox Name="taskList" ItemsSource="{Binding}" ItemTemplate=" 
                     {StaticResource taskItem}" />
              </Expander>
         </DataTemplate>
      </ListBox.ItemTemplate>
   </ListBox>

ロード時に外側のリストボックスに値が入力されます。エキスパンダーが展開されたらItemsSource、内側のリストボックスのプロパティを設定します(バインディングを使用する代わりにこれを行う理由は、この操作が非常に遅く、アイテムを表示することを選択した場合にのみ実行したいからです)。内側のリストボックスは正常にレンダリングされますが、実際CollectionChangedにはコレクションのイベントをサブスクライブしません。ICollection私はこれを の代わりに との代わりにIEnumerableと を追加INotifyPropertyChangedして試しましINotifyCollectionChangedINotifyPropertyChanged。これを実際に機能させる唯一の方法は、SomeCollectionクラスをガットしてから継承することObservableCollection<SomeItem>です。INotifyCollectionChanged使用する代わりに自分自身をロールしようとする私の理由ObservableCollectionこれは、実際のコードで COM コレクションをラップしているためです。INotifyそのコレクションは追加/変更/削除時に通知し、これらをWPF のイベントに変換しようとしています。

これが十分に明確であることを願っています(遅い)。

4

2 に答える 2

0

ObservableCollection<T>また、を実装しINotifyPropertyChangedます。コレクションは単純なものであるIEnumerable<T>ため、イベントを作成するためのプロパティはありませんが、およびプロパティのイベントをObservableCollection<T>作成します。から派生して実装することで、コレクションをより似たものにしようとすることができます。しかし、それで問題が解決するかどうかはわかりません。PropertyChangedCountItem[]ObservableCollection<T>IList<T>INotifyPropertyChanged

于 2009-07-24T10:03:03.983 に答える
0

人々が独自のコレクションを WPF に実装しようとしているのを見続ける理由がわかりません。を使用するだけでObservableCollection<SomeItem>、すべての CollectionChanged 通知が処理されます。

private ObservableCollection<SomeItem> collection = 
    new ObservableCollection<SomeItem>();

で何かをしたい場合はSomeItem.PropertyChangedSomeItem実装してくださいINotifyPropertyChanged

CollectionChanged が発生しない理由については、ItemsSource プロパティを設定していて、バインドしていません。これを設定すると、 のコピーを作成してcollectionに保存することになりListBox.ItemsSourceます。それをバインドするということは、そのデータListBox.ItemsSourceを参照するように指示することを意味しますcollection

于 2011-12-30T18:13:47.187 に答える