2010-01-14 41 views
5

Tôi có một ViewModel có một tài sản mà tôi ràng buộc trong ListView.ItemContainerStyle XAML của tôi để một tài sản trong mô hình quan điểm của tôi IsSelectedIsSelected.WPF Binding IsSelected để ViewModel không đặt mục chưa được hiển thị trong Danh sách

Tôi tải lên ứng dụng và điền vào bộ sưu tập mô hình chế độ xem (được hiển thị trong số ListView) của tôi với nhiều mục, nói khoảng 2000. Sau đó, tôi chọn mọi thứ trong danh sách qua Ctrl-A. Các mục trong bộ sưu tập mô hình chế độ xem của tôi chỉ nhận được số IsSelected được đặt cho các mục được hiển thị trong ListView. Nếu tôi lật trang qua danh sách, IsSelected sẽ được đặt cho bất kỳ mục nào được hiển thị. Nếu tôi trang qua tất cả các mục thì tất cả các mục trong mô hình chế độ xem của tôi có thuộc tính IsSelected được đặt thành true.

Đây là XAML của tôi cho ràng buộc IsSelected trong giao diện danh sách để mô hình quan điểm của tôi:

<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> 

Tại sao không phải là IsSelected cho tất cả các mục trong mô hình quan điểm của tôi thiết lập là true khi tôi chọn tất cả các mục trong ListView?

+0

Nhân tiện, đây thực chất là cùng một câu hỏi như sau: http://stackoverflow.com/questions/1273659/virtualizingstackpanel-mvvm-multiple-selection – Charlie

+0

Cảm ơn Charlie, không biết tôi đã bỏ lỡ bài đăng đó như thế nào. Bài đăng đó có một giải pháp tốt cho vấn đề này là chuyển các mục đã chọn vào dưới dạng CommandParameter thay vì duy trì IsSelected trong mô hình khung nhìn. – Buck

Trả lời

3

Điều này xảy ra do ảo hóa tích hợp của ListView. Nếu bạn không quen thuộc với điều đó, ý nghĩa của nó về cơ bản là các mục không trở thành hiện thực cho đến khi chúng được xem. Bạn có thể tắt ảo hóa của ListView với thuộc tính sau:

VirtualizingStackPanel.IsVirtualizing="False" 

Nhưng hãy cẩn thận điều này sẽ có ảnh hưởng xấu đến hiệu suất của ListView. Đối với 2.000 mục, nó sẽ không nghiêm trọng, nhưng nó có thể là đáng chú ý.

2

Các ListBoxItem được ảo hóa, chúng không tồn tại cho đến khi chúng được tạo ra (khi chúng được đưa vào xem). Tuy nhiên ListView bên dưới có nguồn gốc từ ListBox trong đó có một thuộc tính SelectedItems. SelectedItems là một danh sách tất cả các mục đã chọn không phải là danh sách các ListBoxItems được chọn. Khi ListBoxItem được đưa vào xem thuộc tính IsSelected của nó được thiết lập dựa trên nếu nó là mục (mục nó hiển thị) là trong bộ sưu tập của SelectedItems.

Đây là một biểu tượng cho mô hình chế độ xem của bạn, đặc biệt nếu bạn cần ảo hóa được bật (bạn có thể làm cho 2000 hoặc nhiều mục). Tôi sẽ quan tâm đến câu trả lời cho câu hỏi "Làm thế nào để tôi ràng buộc các mô hình của tôi xem IsSelected tài sản dựa trên nếu một mục là trong một bộ sưu tập SelectedItems của ListBox?"

câu trả lời có lẽ là liên quan đến một chuyển đổi

4

Cách MVVM để làm điều này sẽ được ghi đè Ctrl-A shortcut với lệnh SelectAll của riêng bạn (Tạo một lệnh SellectAll với một phím tắt Ctrl-A). Việc triển khai sẽ thiết lập IsSelected trên các mô hình khung nhìn.

Thuộc tính IsSelected trong chế độ xem của bạn cần có hai cách ràng buộc với mô hình chế độ xem của bạn để các mục xuất hiện được chọn trong chế độ xem của bạn.

Tôi không nghĩ rằng tắt ảo hóa là cần thiết.

Hy vọng điều này sẽ hữu ích.

0

tôi đã cùng một vấn đề và đó là những gì giúp tôi cuối cùng:

Đặt trong ListView của bạn:

VirtualizingStackPanel.VirtualizationMode="Standard" 
0

tôi sẽ gửi câu trả lời này mà tôi tìm thấy trên một diễn đàn khác nhau vì nó giúp tôi với vấn đề.

tôi đã xác định một giao diện ISelectable cho ViewModels của tôi để thực hiện

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

Sau đó, trong MyCustomListView Tôi đã làm điều này:

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); 
    } 
} 

Ngoài ra, bạn có thể làm đăng ký vào các sự kiện SelectionChanged của ListView và sử dụng cùng một mã ở trên.

Các vấn đề liên quan