2009-10-22 46 views
2

我將CollectionViewSource綁定到ListView以分組項目。這一切都很好,除非我更新ObservableCollectionCollectionViewSource是基於。如果我更新集合中的對象的值,UI永遠不會更新。這裏是一個例子:使用CollectionViewSource和DataBinding進行WPF分組

<ListView x:Name="MyListView" Margin="0,0,0,65"> 
    <ListView.GroupStyle> 
     <GroupStyle> 
      <GroupStyle.ContainerStyle> 
       <Style TargetType="{x:Type GroupItem}"> 
        <Setter Property="Margin" Value="0,0,0,5"/> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type GroupItem}"> 
           <Expander IsExpanded="true" BorderBrush="#FFA4B97F" BorderThickness="0,0,0,1"> 
            <Expander.Header> 
             <DockPanel> 
              <TextBlock FontWeight="Bold" Text="{Binding Name}" Margin="5,0,0,0" Width="80"/> 
              <TextBlock FontWeight="Bold" Width="60" TextAlignment="Center" Margin="16,0,0,0" Text="{Binding Items, Converter={StaticResource Converter2}}" /> 
             </DockPanel> 
            </Expander.Header> 
            <ItemsPresenter /> 
           </Expander> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </GroupStyle.ContainerStyle> 
     </GroupStyle> 
    </ListView.GroupStyle> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Width="300" Header="Amount" > 
       <GridViewColumn.CellTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding Amount}" Margin="80,0,0,0"/> 
        </DataTemplate> 
       </GridViewColumn.CellTemplate> 
      </GridViewColumn> 
     </GridView> 
    </ListView.View> 
</ListView> 

你會注意到它調用了一個轉換器在組中,並給它的項目集合。這是爲了讓轉換器可以計算的平均行並返回結果:

public class AverageConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     IEnumerable<object> rows = (IEnumerable<object>) value; 
     double average = rows.Average(a => ((DisplayRow) a).Amount); 
     return average; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

後面的代碼中我添加行和創建CollectionViewSource

私人只讀的ObservableCollection displayRows =新的ObservableCollection() ;

public Window1() 
{ 
    InitializeComponent(); 

    displayRows.Add(new DisplayRow { Title = "Sales", Amount=16}); 
    displayRows.Add(new DisplayRow { Title = "Marketing", Amount=14}); 
    displayRows.Add(new DisplayRow { Title = "Technology", Amount=13}); 
    displayRows.Add(new DisplayRow { Title = "Sales", Amount=11}); 
    displayRows.Add(new DisplayRow { Title = "Marketing", Amount=13}); 
    displayRows.Add(new DisplayRow { Title = "Technology", Amount=12}); 
    CollectionViewSource viewSource = new CollectionViewSource { Source = displayRows }; 
    viewSource.GroupDescriptions.Add(new PropertyGroupDescription("Title")); 
    MyListView.ItemsSource = viewSource.View; 
} 

DisplayRow的對象實現INotifyPropertyChanged,並且僅僅是一個簡單的類。

一切正常,顯示器是我想要的方式,但如果我更改ObservableCollection中的值,則UI不會更改。

如果我添加一個元素到集合中,我可以看到它出現在屏幕上,但轉換器永遠不會被調用來重新計算平均值。有任何想法嗎?

回答

4

我發現瞭解決這個問題的方法。

private CollectionViewSource _viewSource; 

private void ModifyData() 
{ 
    // Modify some data 

    // This will cause the ListView to refresh its data and update the UI 
    // and also cause the converter to be called to reformat the data. 
    _viewSource.View.Refresh(); 
} 

希望有幫助。

+0

不錯。是的,它確實有幫助。不幸的是,我需要更新整個事情,但至少它讓我受到這個問題的困擾。謝謝。 – Kelly 2009-10-26 15:47:44

1

如果數據源是一個ObservableCollection,無論何時當有添加或刪除它的項目集合更改即視圖將被更新。如果希望在編輯底層數據時更新視圖,那麼該類必須實現INotifyPropertyChanged接口。

在你的情況DisplayRow類必須實現INotifyPropertyChanged和displayRows應該是一個ObservableCollection。

這是官方的做法,從我的理解。我可能錯了。