2009-04-24 26 views
4

IListをカンマ区切りの文字列(たとえば「Item1、Item2、Item3」)に変換できるCollectionToStringConverterを作成しました。コレクションが変更されたときにコンバータが呼び出されないのはなぜですか?

私はこのようにそれを使用します。一度だけ、私はUIをロードする際

<TextBlock Text="{Binding Items, 
        Converter={StaticResource CollectionToStringConverter}}" /> 

上記作品、しかし。 ItemsObservableCollectionです。テキストブロックは更新されず、Itemsに追加または削除するとコンバータが呼び出されません。

これを行うには何が欠けていますか?

答えて

6

バインディングは、コレクションを生成するプロパティです。コレクション内の項目が変更されたときではなく、コレクションインスタンス自体が変更されるたびに有効になります。

1)コレクションにItemsControlをバインドし、それが最後の項目ではない場合、出力にカンマが先行するテキストをItemTemplateを設定します含め、必要な動作を実現するにはかなりの数の方法がありますが、

コレクション。ような何か:

<ItemsControl ItemsSource="{Binding Items}"> 
    <ItemsControl.ItemTemplate> 
     <TextBlock> 
      <TextBlock Visibility="{Binding RelativeSource={RelativeSource PreviousData}, Converter={StaticResource PreviousDataConverter}}" Text=", "/> 
      <TextBlock Text="{Binding .}"/> 
     </TextBlock> 
    </ItemsControl.ItemTemplate>  
</ItemsControl> 

2)変更のためのコレクションを見て、単一stringにアイテムを連結する別のプロパティを更新するために、あなたのコードビハインドでコードを記述します。以下のような何か:

public ctor() 
{ 
    _items = new ObservableCollection<string>(); 

    _items.CollectionChanged += delegate 
    { 
     UpdateDisplayString(); 
    }; 
} 

private void UpdateDisplayString() 
{ 
    var sb = new StringBuilder(); 

    //do concatentation 

    DisplayString = sb.ToString(); 
} 

3)#2と同様の独立した連結文字列を維持し、独自のObservableCollection<T>サブクラスを書きます。

+0

ように私は実際にItemsTemplateのアプローチを使用してオフに開始したことになるが、コードレビューの際に、我々はそれが簡単になるだろうと思いました観察されたコレクションが変更されたときにバインディングが更新されると考えて、マルチバインディングコンバータを使用してください。私はその方法に戻ってきます:)ありがとう! –

+1

例のItemsControl.ItemTemplateと最初のTextBlock要素の間にDataTemplateがありません。 – jpierson

1

プロパティは、プロパティが変更されたときにのみ呼び出されます。この場合、 'Items'の値は変更されません。コレクションに新しい項目を追加または削除すると、バインディング部分はそれを認識しません。

ObservableCollectionを拡張し、新しいStringプロパティをit.Rememberに追加して、CollectionChangedイベントハンドラのそのプロパティを更新することができます。ここで

は実装

public class SpecialCollection : ObservableCollection<string>, INotifyPropertyChanged 
{ 

    public string CollectionString 
    { 
     get { return _CollectionString; } 
     set { 
      _CollectionString = value; 
      FirePropertyChangedNotification("CollectionString"); 
     } 
    } 


    protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     string str = ""; 

     foreach (string s in this) 
     { 
      str += s+","; 
     } 

     CollectionString = str; 

     base.OnCollectionChanged(e); 
    } 

    private void FirePropertyChangedNotification(string propName) 
    { 
     if (PropertyChangedEvent != null) 
      PropertyChangedEvent(this, 
       new PropertyChangedEventArgs(propName)); 
    } 

    private string _CollectionString; 
    public event PropertyChangedEventHandler PropertyChangedEvent; 

} 

であり、あなたのXAMLは

<TextBlock DataContext={Binding specialItems} Text="{Binding CollectionString}" /> 
関連する問題