2012-03-30 32 views
23

Hiện tại chúng tôi có một số DataGrid được gắn với DataTable. Nó cũng có một cột mẫu với một CheckBox trong nó mà chúng ta thêm vào theo chương trình. Mục đích của cột này là theo dõi nhiều lựa chọn trong số DataGrid.Vấn đề hiển thị ảo hóa DataGrid hàng

Nhà máy được sử dụng để tạo CheckBox es cho mỗi hàng.

Có một vài bản ghi, vì vậy việc ảo hóa hàng được đặt thành true để hiệu suất có thể chấp nhận được. Tuy nhiên, chúng ta đang thấy một vấn đề lạ khi chúng ta kiểm tra một số CheckBox es trên 10 hàng đầu tiên và sau đó cuộn xuống khoảng 50 hàng (lưới có khoảng 10 hàng có thể nhìn thấy bất kỳ lúc nào), có một số khác CheckBox es dường như được kiểm tra ngẫu nhiên.

Nếu chúng tôi tắt tính năng ảo hóa hàng thì vấn đề này không tồn tại (nhưng hiệu suất là khủng khiếp). Có cách nào để khắc phục điều này? Bất cứ ai biết những gì chúng tôi có thể làm sai?

+0

khi bạn nói hiệu suất là khủng khiếp sau khi xóa ảo hóa, thật khủng khiếp khi tải hoặc khi cuộn. Nếu nó được tải, có một giải pháp mà sẽ làm cho nó không khủng khiếp, trên di chuyển là một vấn đề khác ... –

+0

Nó chỉ được tải. Tất cả các hit hiệu suất là trên Show phương pháp của cửa sổ có chứa DataGrid. Với việc ảo hóa hàng, nó sẽ hiển thị 200ms để hiển thị với 2.500 bản ghi trong DataGrid. Nếu không có ảo hóa hàng thì mất 28 giây. – WPFNewbie

+0

đã thêm một số mã cho bạn ... chỉ cần tinh chỉnh hiệu suất tại nơi làm việc vài ngày trước, hoạt động như một nét duyên dáng –

Trả lời

23

Nếu bạn đang tìm kiếm tốc độ ListView GridView nhanh hơn nhiều (và có ít tính năng hơn).

Hãy thử hủy tái chế thùng chứa.

   <tk:DataGrid x:Name="dataGrid" 
      ItemsSource="{Binding Path=Bookings}" 
      AutoGenerateColumns="False" 
      EnableRowVirtualization="True" 
      EnableColumnVirtualization="True" 
      VirtualizingStackPanel.VirtualizationMode="Standard" 
      VirtualizingStackPanel.IsVirtualizing="True"> 
+3

Nếu bạn viết IsVirtualising trước VirtualisationMode, bạn có ngoại lệ (ít nhất là trong .NET 4.5) ... bạn cần thay đổi thứ tự –

+0

Tôi gặp vấn đề tương tự, ngoại trừ thứ tự của các hàng được thay đổi khi tôi đang di chuyển. Tôi đã không thực hiện ảo hóa một cách rõ ràng. Câu trả lời này đã giúp, tuy nhiên. –

+0

VirtualizationMode = "Tiêu chuẩn" cho chiến thắng! –

4

Nếu bạn bật Virtualization vì thời gian DataGrid tải là khủng khiếp, sau đó, đây là giải pháp:

  • tắt ảo
  • hãy giả/gọi nguồn mục của DataGrid của bạn ràng buộc là " Hàng ",

    public IEnumerable<Row> Rows {get; set;} 
    
  • Thêm thuộc tính vào lớp" Hàng "của bạn IsVisible và chuyển đổi nó khi bạn muốn tải dữ liệu (không phải khi thread UI quyết định để giải quyết ràng buộc và tải từng kiểm soát)

lý do công trình này, là vì khi bạn tải lưới điện, nó sẽ kiểm tra các ràng buộc, tất cả hàng là vô hình, do đó, các chủ đề giao diện người dùng không phải quay qua tất cả các hàng của bạn * cột để tạo ra chúng, nó có thể đi đến điều tiếp theo nó cần phải làm. Mặt khác, bạn có thể phát hiện khi nào là thời gian thuận tiện để biến những hàng đó thành hiển thị, khi View.Visibility hiển thị, khi ViewModel tải dữ liệu từ đâu đó, v.v. Vì vậy, bạn có toàn quyền kiểm soát. Dưới đây tôi đang lặp qua nguồn mục (hàng) của tôi bằng cách sử dụng một nhiệm vụ (trong một chủ đề nền), nhưng thiết lập khả năng hiển thị trên chuỗi giao diện người dùng.

private _isVisible = false; 

    /// <summary> 
    /// is false by default, for performance when loading first time. 
    /// </summary> 
    public bool IsVisible 
    { 
     get { return _isVisible; } 
     set 
     { 
      if (_isVisible == value) 
       return; 
      _isVisible = value; 
      RaisePropertyChanged(() => IsVisible); 
     } 
    } 
  • Trong View, khi DataGrid là tải không cho phép nó hog thread UI bằng cách đặt lặp hàng trong thread nền, sau đó thiết lập Visibility là true. Mặc dù bạn đang ở trên chuỗi nền, thuộc tính IsVisible đã thay đổi sẽ kích hoạt bạn cập nhật.

    private void OnGridLoaded(object sender, RoutedEventArgs e) 
    { 
        //sample bool checks, you might not need them... 
        if (firstTimeLoad && !_isDataGridLoaded) 
        { 
         Task.Factory 
          .StartNew(() => 
          { 
           /*first time loading performance tweak*/ 
           foreach (var row in _viewModel.Rows) 
            ExeOnUi(() => { row.IsVisible = true; }); 
    
           _firstTimeLoad = false; 
          }) 
        } 
    
  • quên thêm mã ExeOnUi (bạn có thể kiểm tra quyền truy cập sử dụng cái gì khác như whateverControl.Dispatcher.CheckAccess, tôi chỉ sử dụng Microsoft.Practices.ServiceLocator):

    static void ExeOnUi (Action action) 
    { 
        var srv= ServiceLocator.Current.GetInstance<IDispatchService>(); 
        if (srv.CheckAccess()) 
         action.Invoke(); 
        else 
         srv.Invoke (action); 
    } 
    
1

Tôi chỉ cần chạy vào vấn đề tương tự và giải quyết nó sau khi thêm UpdateSourceTrigger=PropertyChanged đến các ràng buộc.

<DataGridTemplateColumn Header="Visible"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <CheckBox IsChecked="{Binding IsShown,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 
Các vấn đề liên quan