【发布时间】:2010-11-13 15:53:55
【问题描述】:
我有以下测试代码:
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 以及将INotifyCollectionChanged 替换为INotifyPropertyChanged。我实际上可以让它工作的唯一方法是删除我的SomeCollection 类并从ObservableCollection<SomeItem> 继承。我尝试扮演我自己的INotifyCollectionChanged 而不是使用ObservableCollection 的原因是因为我在真实代码中包装了一个COM 集合。该集合将通知添加/更改/删除,我正在尝试将这些转换为 WPF 的 INotify 事件。
希望这已经足够清楚了(为时已晚)。
【问题讨论】:
-
我猜这是因为您没有充分实现
INotifyCollectionChanged行为,而且您根本没有实现INotifyPropertyChanged。寻找具体原因可能不值得调查,因为您最好将SomeCollection更改为从ObservableCollection<T>继承并为您完成很多工作。为什么要重新发明轮子?如果需要,您仍然可以重写方法来自定义其行为。 -
您是否获得了有关您要包装的 COM 集合的更多详细信息?我认为您应该问如何将您的 COM 集合转换为 ObservableCollection。
标签: wpf observablecollection inotifypropertychanged inotifycollectionchanged