2010-01-14 55 views
5

被證明我有一個ViewModel有我在我的ListView.ItemContainerStyle XAML綁定到我的視圖模型的IsSelected財產IsSelected屬性的項目。WPF綁定IsSelected到視圖模型不設置那些不在列表中

我提出申請,並填充視圖模型集合(這是在我的ListView圖示),項目很多,說一下2000。然後我通過按Ctrl-A選擇列表中的所有內容。我的視圖模型集合中的項目只能獲得爲ListView中可見項目設置的IsSelected。如果我在列表中向下翻頁,IsSelected會被設置爲顯示的任何項目。如果我翻閱所有項目,則我的視圖模型中的所有項目都將IsSelected屬性設置爲true。

這裏是我的列表視圖綁定IsSelected到我的視圖模型XAML:

<ListView Margin="5" ItemsSource="{Binding FilteredComparisonList}" x:Name="comparisonListView"> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="{x:Type ListBoxItem}"> 
      <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" /> 
     </Style> 
    </ListView.ItemContainerStyle> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="Source filename" DisplayMemberBinding="{Binding ImageFile.BaseFilename}" Width="Auto" /> 
     </GridView> 
    </ListView.View> 
</ListView> 

爲什麼不IsSelected在我的視圖模型中的所有項目設置爲true時,我選擇所有項目在ListView

+0

順便說一下,這本質上是一樣的問題,因爲這: http://stackoverflow.com/questions/1273659/virtualizingstackpanel-mvvm-multiple-selection – Charlie 2010-01-14 23:07:48

+0

謝謝查理,不知道我錯過了那個職位。該帖子很好地解決了這個問題,即將所選項目作爲CommandParameter傳遞,而不是在視圖模型中維護IsSelected。 – Buck 2010-01-14 23:36:33

回答

3

這是因爲ListView的內置虛擬化而發生的。如果你不熟悉這一點,它的基本意思是這些物品在它們看不到的時候纔會變成真實的。您可以關閉ListView的虛擬化具有以下特性:

VirtualizingStackPanel.IsVirtualizing="False" 

但要注意這會對你的ListView的性能產生負面影響。對於2000件物品來說不會很嚴重,但它可能是顯而易見的。

2

ListBoxItem是虛擬化的,它們在生成之前不存在(當它們被引入視圖時)。但是,底層ListView是從具有SelectedItems屬性的ListBox派生的。 SelectedItems是所有選定項目的列表,而不是所選ListBoxItems的列表。當ListBoxItem被帶入視圖中時,它的IsSelected屬性被設置爲基於它的項目(它顯示的項目)是否在SelectedItems的集合中。

這是您的視圖模型的一個特徵,特別是當您需要虛擬化時(您可能會爲2000左右的項目所做)。我會對這個問題的答案感興趣:「如何根據ListBox的SelectedItems集合中的項目來綁定我的視圖模型IsSelected屬性?」

答案可能涉及到一個轉換器

4

的MVVM方式做,這將是覆蓋按Ctrl-A快捷鍵與自己的選命令(使用Ctrl-A的快捷方式創建一個SellectAll命令)。該實現將在視圖模型上設置IsSelected。

您視圖中的IsSelected屬性需要對視圖模型進行雙向綁定,以便在視圖中顯示選定的項目。

我不認爲關閉虛擬化是必要的。

希望這會有所幫助。

0

我有同樣的問題,這就是最後幫助我:你ListView

地說:

VirtualizingStackPanel.VirtualizationMode="Standard" 
0

我會後這個答案,我在不同的論壇發現,因爲它幫助我問題。

我已經定義的接口ISelectable我的ViewModels實施

public interface ISelectable 
{ 
    bool IsSelected { get; set; } 
} 

然後在MyCustomListView我已經做到了這一點:

public class MyCustomListView : ListView 
{ 
    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     foreach (var item in e.AddedItems.OfType<ISelectable>()) 
      item.IsSelected = true; 

     foreach (var item in e.RemovedItems.OfType<ISelectable>()) 
      item.IsSelected = false; 

     base.OnSelectionChanged(e); 
    } 
} 

或者,你可以做訂閱到ListView的SelectionChanged事件並使用上面的相同代碼。