2011-12-22 61 views
2

我有非常大的網格。我想使用複選框「檢查/取消全選」,這將檢查/取消選中所有行。但它很慢,因爲有很多OnPtopertyChanged事件的調用。我如何才能引發OnPropertyChanged事件只爲可見元素?行的虛擬化已啓用。如何僅爲可見元素引發OnPropertyChanged?

+0

您在這裏挑戰WPF的基礎知識。沒有簡單的方法做到這一點。你有沒有考慮使用分頁? – 2011-12-22 09:36:49

+0

分頁可能會混淆的是「全部檢查」檢查所有頁面上的所有元素或僅在當前頁面上。 – Rover 2011-12-22 09:41:00

+0

如何設置檢查/取消選中所有行?請發佈此代碼 – blindmeis 2011-12-22 09:41:58

回答

0

第一種方法:取出OnPropertyChanged的認識和添加dataGrid.Items.Refresh();

第二種方法:在後臺更改屬性,然後

var rows = grid.FindChildren<DataGridRowsPresenter>().First() as DependencyObject; 
int count = VisualTreeHelper.GetChildrenCount(rows); 
for (int i = 0; i < count; i++) 
{ 
    DataGridRow row = VisualTreeHelper.GetChild(rows, i) as DataGridRow; 
    (row.DataContext as IViewModel).Refresh();//Refresh invokes OnPropertyChanged 
} 
0

處理此問題的一種方法是在ViewModel中具有boolean IsVisible屬性。如果IsVisible只返回true,那麼您可以提高PropertyChanged事件。

+1

唯一的問題是如何爲虛擬網格設置這些IsVisible標誌:) – 2011-12-22 09:25:49

+0

我的意思是說你的MV :) – 2011-12-22 09:39:35

1

20000行很多:)

如果斷開的ItemsSource綁定改變你的列表視圖模型的和的ItemsSource設置爲新的檢查清單會發生什麼?如果他們想20000rows他們可以等待它

oterwise;)

編輯

如果你不改變你的ItemsSource你必須提高的PropertyChanged對每一個項目,否則你沒有看到的變化。

另一種方式是設置綁定爲空或新的列表

this.MyGridItemsViewModelProperty = new List();//"disconnect" the binding to the grid for the all check/uncheck 

然後改變你與選中/清除實時列表,並把它設回爲網格的ItemsSource

this.MyGridItemsViewModelProperty = myupdatelist; 

電網

<Grid ItemsSource="{Binding MyGridItemsViewModelProperty}" /> 

但我不知道如果第二種方法更快,你應該測試它。

+0

我該如何斷開連接然後連接相同的DataSource?它只刷新隱藏的元素。但它工作得更快。 – Rover 2011-12-22 10:18:41

+0

你寫的check/unckeck是非常慢的 - 現在你寫的非常快?真正的問題是什麼?也許你應該發佈你的datagrid綁定xaml,觸發器和你的viewmodel。 – blindmeis 2011-12-22 10:30:38

+0

問題出在OnPropertyChanged上。如果我在每個元素的每個檢查上調用它,它的工作速度會很慢。我刪除它,它運行得很快,但UI不顯示更改。所以,我只需要刷新UI的可見部分。 – Rover 2011-12-22 10:33:52

0

更新1我創建了一個具有100K行的簡單repro,並在我的低規格PC上飛行,您可以檢查一下它並確認它是否足夠快?項目名稱GroupSelect然後只是複製/過去的東西到主窗口。

代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.ComponentModel; 
using System.Collections.ObjectModel; 
using System.Collections.Specialized; 

namespace GroupSelect 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      this.Loaded += 
       (o, e) => 
       { 
        this.DataContext = 
         new Model(100000); 
       }; 
     } 
    } 

    public class Model : INotifyPropertyChanged 
    { 
     private bool? isAllSelected = null; 

     public Model(int itemCount) 
     { 
      this.Items = 
       Enumerable.Range(1, itemCount).Select(t => 
        new Item(this) 
       { 
        Name = "n_" + t.ToString() 
       }).ToList(); 

      this.IsAllSelected = false; 
     } 

     public List<Item> Items 
     { 
      get; 
      private set; 
     } 

     public bool? IsAllSelected 
     { 
      get 
      { 
       return this.isAllSelected; 
      } 
      set 
      { 
       if (this.IsAllSelected != value) 
       { 
        this.IsBatchUpdate = true; // updating 

        this.isAllSelected = value; 

        if (this.PropertyChanged != null) 
        { 
         this.PropertyChanged(this, 
          new PropertyChangedEventArgs("IsAllSelected")); 
        } 

        // 
        if (this.IsAllSelected.HasValue) 
        { 
         foreach (Item i in this.Items) 
         { 
          i.IsSelected = value.Value; 
         } 
        } 

        this.IsBatchUpdate = false; // updating 
       } 
      } 
     } 

     public bool IsBatchUpdate 
     { 
      get; 
      private set; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 

    public class Item: INotifyPropertyChanged 
    { 
     private bool isSelected = false; 

     public Item(Model model) 
     { 
      this.Model = model; 
     } 

     public Model Model 
     { 
      get; 
      private set; 
     } 

     public string Name 
     { 
      get; 
      set; 
     } 

     public bool IsSelected 
     { 
      get 
      { 
       return this.isSelected; 
      } 
      set 
      { 
       if (this.IsSelected != value) 
       { 
        this.isSelected = value; 

        if (this.PropertyChanged != null) 
        { 
         this.PropertyChanged(this, 
          new PropertyChangedEventArgs("IsSelected")); 
        } 

        if (!this.Model.IsBatchUpdate) 
        { 
         this.Model.IsAllSelected = null; 
        } 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

標記:

<Window x:Class="GroupSelect.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:GroupSelect" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <DataGrid x:Name="g" AutoGenerateColumns="False" 
        ItemsSource="{Binding Path='Items'}"> 
      <DataGrid.Columns> 
       <DataGridCheckBoxColumn Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"> 
        <DataGridCheckBoxColumn.HeaderTemplate> 
         <DataTemplate> 
          <CheckBox HorizontalAlignment="Center" 
             DataContext="{Binding Path=DataContext, 
             RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
             IsChecked="{Binding Path=IsAllSelected, UpdateSourceTrigger=PropertyChanged}"/> 
         </DataTemplate> 
        </DataGridCheckBoxColumn.HeaderTemplate> 
       </DataGridCheckBoxColumn> 
       <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 
+0

問題是,所有集合都發生更改的通知不會生效,而我根本不會更改它。 grid.ItemsSource = null; grid.ItemsSource = elements; - 它不適用於可見行,但會影響滾動下的元素。此外,RaisePropertyChanged((()=> Elements)不起作用。 – Rover 2011-12-22 10:29:56

+0

請找到更新的解決方案。 – 2011-12-22 11:32:58