Ich habe den folgenden Testcode:WPF ListBox Bindung nicht zu INotifyCollectionChanged oder INotifyPropertyChanged Events
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;
}
und die 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>
die äußere listbox auf Last bevölkert wird. wenn der Expander expandiert wird ich dann den ItemsSource
Eigenschaft des inneren listbox (der Grund, warum ich diese stattdessen Bindung hören Sie zu verwenden, ist dieser Vorgang ziemlich langsam ist, und ich will es nur stattfinden, wenn die Verwendung der Elemente anzuzeigen, wählt). Das innere Listenfeld wird ordnungsgemäß gerendert, es wird jedoch nicht tatsächlich für das Ereignis CollectionChanged
der Sammlung abonniert. Ich habe schon versucht, diese mit ICollection
statt IEnumerable
und das Hinzufügen von INotifyPropertyChanged
sowie Ersatz INotifyCollectionChanged
mit INotifyPropertyChanged
. Der einzige Weg, wie ich das zum Laufen bringen kann, ist meine SomeCollection
Klasse zu erben und von ObservableCollection<SomeItem>
zu erben. Meine Argumentation für den Versuch, meine eigene INotifyCollectionChanged
anstelle von ObservableCollection
zu verwenden, ist, weil ich eine COM-Sammlung in den echten Code verpacken. Diese Sammlung benachrichtigt bei Hinzufügen/Ändern/Entfernen und ich versuche, diese in INotify
Ereignisse für WPF zu konvertieren.
Hoffnung ist klar genug (sein spät).
Ich vermute, es ist, weil Sie 'INotifyCollectionChanged' Verhalten nicht ausreichend implementieren, und Sie implementieren nicht' INotifyPropertyChanged' überhaupt. Es lohnt sich wahrscheinlich nicht, die spezifischen Gründe zu ermitteln, da Sie besser 'SomeCollection' von ObservableCollection erben und viel für Sie erledigen müssen. Warum erfinden Sie das Rad neu? Sie können weiterhin Methoden überschreiben, um das Verhalten bei Bedarf anzupassen. –
Haben Sie weitere Details zu der COM-Sammlung, die Sie umbrechen möchten? Ich denke, Sie sollten sich fragen, wie Sie Ihre COM-Sammlung in eine ObservableCollection konvertieren. – Iain