2009-04-24 51 views
4

我做了一個CollectionToStringConverter,它可以將任何IList轉換成以逗號分隔的字符串(例如「Item1,Item2,Item3」)。爲什麼Collection在Collection更改時未被調用?

我用這樣的:

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

上述作品,但只有一次,當我加載UI。 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)自己寫的ObservableCollection<T>子類,維持類似#2一個單獨的連接字符串。

+0

我已經使用ItemsTemplate做法其實已經開始了,但代碼審查過程中,我們認爲這將是簡單通過一個多結合轉換器來完成,當觀察到的集合發生變化時,認爲綁定會被更新。我會恢復到該方法:)謝謝! – 2009-04-24 19:37:18

1

只有在屬性更改時纔會調用轉換器。在這種情況下,'Items'值不會改變。當您向集合中添加或刪除新項目時,綁定部分不知道這一點。

您可以擴展ObservableCollection並在其中添加一個新的String屬性。請記住在您的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}" /> 
相關問題