Если то, что собирает Axes, не является классом со своим собственным свойством Name, то свойство DisplayMemberPath = "Name" может привести к тому, что вы ничего не увидите.
Использование KeyedCollection в качестве ItemsSource прекрасно, хотя. Свойство ItemsSource является свойством ItemsControl.ItemsSource . И это просто требует, чтобы все, к чему он привязан, реализовывало IEnumerable.
KeyedCollection действительно реализует IEnumerable, так как он реализует Collection.
Вот небольшой пример использования KeyedCollection:
<Grid>
<DockPanel x:Name="QuickListButtonsStackPanel">
<Button DockPanel.Dock="Top"
Content="Load Animals"
Click="AnimalButtonClick" />
<Button DockPanel.Dock="Top"
Content="Load Objects"
Click="ObjectButtonClick" />
<TextBlock DockPanel.Dock="Bottom"
Background="Azure"
Text="{Binding SelectedExample}" />
<ListBox x:Name="uiListBox"
ItemsSource="{Binding Examples}"
SelectedItem="{Binding SelectedExample}" />
</DockPanel>
</Grid>
И код для нашей Window & KeyedCollection:
public partial class Window1 : Window, INotifyPropertyChanged
{
public Window1()
{
InitializeComponent();
this.DataContext = this;
}
public KeyedCollection<char, string> Examples
{
get;
set;
}
private string mySelectedExample;
public string SelectedExample
{
get
{ return this.mySelectedExample; }
set
{
this.mySelectedExample = value;
this.NotifyPropertyChanged("SelectedExample");
}
}
private void AnimalButtonClick(object sender, RoutedEventArgs e)
{
Examples = new AlphabetExampleCollection();
Examples.Add("Ardvark");
Examples.Add("Bat");
Examples.Add("Cat");
Examples.Add("Dingo");
Examples.Add("Emu");
NotifyPropertyChanged("Examples");
}
private void ObjectButtonClick(object sender, RoutedEventArgs e)
{
Examples = new AlphabetExampleCollection();
Examples.Add("Apple");
Examples.Add("Ball");
Examples.Add("Chair");
Examples.Add("Desk");
Examples.Add("Eee PC");
NotifyPropertyChanged("Examples");
}
#region INotifyPropertyChanged Members
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public class AlphabetExampleCollection : KeyedCollection<char, string>
{
public AlphabetExampleCollection() : base() { }
protected override char GetKeyForItem(string item)
{
return Char.ToUpper(item[0]);
}
}
Другая проблема, которая может возникнуть, заключается в том, что вы просто добавляете / удаляете элементы из коллекции, а не переустанавливаете коллекцию. В приведенном выше примере вы видите, что мы восстанавливаем коллекцию ключей. Если бы мы этого не делали, то просто вызов NotifyPropertyChanged ничего бы не сделал.
Давайте добавим еще две кнопки, чтобы продемонстрировать это:
<Button DockPanel.Dock="Top"
Content="Add Zebra"
Click="AddZebraClick" />
<Button DockPanel.Dock="Top"
Content="Add YoYo"
Click="AddYoYoClick" />
И Хандлерс:
private void AddZebraClick(object sender, RoutedEventArgs e)
{
Examples.Add("Zebra");
NotifyPropertyChanged("Examples");
}
private void AddYoYoClick(object sender, RoutedEventArgs e)
{
Examples.Add("YoYo");
NotifyPropertyChanged("Examples");
}
Оба из них, как и , не будут работать . Когда вы вызываете NotifyPropertyChanged, свойство должно быть фактически изменено. И в этом случае это не так. Мы изменили его элементы, но коллекция примеров остается той же самой. Чтобы исправить это, мы могли бы циклично собирать коллекцию, как мы это делали в первой части, или, если у нас есть доступ к пользовательскому интерфейсу, мы могли бы вызвать:
uiListBox.Items.Refresh();
Мы могли бы также циклически переключать DataSource, мы могли бы циклически обрабатывать ItemsSource ListBox, или мы могли бы очистить и переназначить привязку, но простой вызов UpdateTarget () не сделает этого, однако.