2009-06-03 11 views
1

私はWPF Databindingの初心者です。ちょっと混乱します。たぶん誰かが私を助けることができます。データバインディングwpf KeyedCollection

を私のXAMLコードはリストにリストボックスをバインド:

<ListBox ItemsSource="{Binding Path=Axes}" SelectedItem="{Binding Path = SelectedAxis}" DisplayMemberPath = "Name" Name="listboxAxes"/> 

にバインドされている実際のアイテムは予想通りリストのすべての作品である場合。

しかし、KeyedCollectionに変更すると、更新の問題が発生します。 NotifyPropertychanged( "Axes")を呼び出すと、ListBox全体が更新されることはありません。

これについてのアイデアは?

+0

あなたはコードとしてXAMLコードをマークする必要がありますか、あなたの質問に表示されません。 –

答えて

4

軸が収集されているものならば、DisplayMemberPath =「名前」プロパティは、あなたが何も見えないように原因することができるそれ自身のNameプロパティを持つクラスではありません。

ItemsSourceとしてKeyedCollectionを使用しても問題ありません。 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> 

そして、我々のウィンドウ& 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を呼び出すだけで何もできません。 を動作しませんであるとして、これらの両方

private void AddZebraClick(object sender, RoutedEventArgs e) 
{ 
    Examples.Add("Zebra"); 
    NotifyPropertyChanged("Examples"); 
} 

private void AddYoYoClick(object sender, RoutedEventArgs e) 
{ 
    Examples.Add("YoYo"); 
    NotifyPropertyChanged("Examples"); 
} 

<Button DockPanel.Dock="Top" 
     Content="Add Zebra" 
     Click="AddZebraClick" /> 
<Button DockPanel.Dock="Top" 
     Content="Add YoYo" 
     Click="AddYoYoClick" /> 

そしてHanlders:

はこれを実証するために、2つの以上のボタンに追加できます。 NotifyPropertyChangedを呼び出すと、プロパティが実際に変更されている必要があります。そして、この場合、そうではありません。アイテムを修正しましたが、例コレクションはまだ同じコレクションです。私たちはUIへのアクセス権を持っている場合、我々はサイクルのコレクションを、我々は最初の部分で行ったようでしこれを修正するには、または、我々は呼び出すことができます。

uiListBox.Items.Refresh(); 

我々可能性もサイクルのDataSource、我々でしサイクルのListBoxののItemsSource、バインディングをクリアして再割り当てすることもできますが、UpdateTarget()を呼び出すだけでバインディングを行うことはできません。

2

listboxAxes.Items.Refresh()を呼び出してみてください。 これはときどき役立ちます。

+0

それはおそらく動作します。しかし、私たちはコードを追加したくありません。デフォルトバインディングの仕組みだけで動作するはずです。 – Matze

+0

私はKeyedCollectionにバインド経験がありません。だから私は他の誰かがあなたを助けるためにabledされることを願っています。 –

2

KeyedCollectionINotifyCollectionChangedINotifyPropertyChangedも実装していません。バインディングを自動的に更新するには、これらのインターフェイスを実装するコレクションを使用します(たとえば、ObservableCollection)。

+0

それは、KeyCollectionの要素についてではありません... それは完全に新しいKeyCollectionオブジェクトについてです。変更はNotifyPropertyChanged(..)イベントによって適切に通知されます。 – Matze

0

はIListの型付けされたプロパティとしてあなたの財産を公開し、このプロパティにItemSourceをバインド:

public IList MyIListKeyedCollection { get { return myKeyedCollection; } } 

を、コールがNotifyPropertyChanged(「My​​IListKeyedCollection」)たびmyKeyedCollectionの変更を行います。私はそれがうまくいくはずだと思う...

関連する問題