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替换。我实际上可以让它工作的唯一方法是破坏我的类并继承自. 我试图扮演自己的角色而不是使用的理由INotifyCollectionChangedINotifyPropertyChangedSomeCollectionObservableCollection<SomeItem>INotifyCollectionChangedObservableCollection是因为我在真实代码中包装了一个 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.PropertyChanged,请SomeItem实施INotifyPropertyChanged

至于为什么您的 CollectionChanged 没有被提出,您正在设置ItemsSource 属性,而不是绑定它。设置它意味着您正在制作副本collection并将其存储在ListBox.ItemsSource. 绑定它意味着你会告诉你ListBox.ItemsSource要引用collection它的数据。

于 2011-12-30T18:13:47.187 回答