我有以下测试代码:
外部列表框在加载时被填充。当展开器被展开时,我设置了内部列表框的
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>
,让它为您完成大部分工作。何必重复造轮子?如果需要,您仍然可以重写方法以自定义其行为。 - Sean Hanley