簡體   English   中英

WPF Datagrid 延遲加載

[英]WPF Datagrid Lazy load

細節

  1. VS-2008 專業版 SP1
  2. .net 3.5 版本
  3. 語言:C#

我有一個 WPF Datagrid,它從 Linq-sql 查詢 Datacontext 數據項加載。結果集包含大約 200k 行,加載它們、排序、過濾等非常慢。提高速度的簡單方法是什么?

我在搜索中看到的幾件事是 Scrollview、數據虛擬化等人們也談論分頁、分析等

加載數據: 200k 行是很多數據,沒有人(用戶)想在一個地方看到。 它肯定會降低您的 UI 用戶體驗。 所以你最好的辦法是過濾你的數據以減少它的數量(例如不顯示已關閉的訂單,只顯示未結訂單)。 如果你不能這樣做,你應該使用虛擬化。 我沒有看到任何使用分頁來顯示數據的應用程序(當然,網絡除外)。 大多數時候這不是一個好方法。 但是,如果您談論的是一種類似於搜索引擎結果的數據類型,則必須使用它。 但請記住,大多數用戶在搜索引擎結果中不會超過第 10 頁。

過濾:我建議在您的服務器端為如此大量的數據(此處為 SQL Server)進行過濾,或者正如我所說的,首先過濾整個 200k 以減少服務器端的數量,然后按順序過濾它(為用戶)在客戶端找到一些東西。 您可能還會發現以下鏈接很有幫助:

  1. http://www.codeproject.com/KB/WPF/DataGridFilterLibrary.aspx

排序:我再次建議服務器-客戶端解決方案,但您可能還會發現以下鏈接有用:

  1. http://blogs.msdn.com/b/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
  2. http://blogs.msdn.com/b/jgoldb/archive/2008/08/28/improving-microsoft-datagrid-ctp-sorting-performance-part-2.aspx
  3. http://blogs.msdn.com/b/jgoldb/archive/2008/10/30/improving-microsoft-datagrid-sorting-performance-part-3.aspx

許多人不使用 WPF 數據網格的默認SortMemberPath只是因為它對每條記錄使用反射,這將大大降低排序過程的性能。

侯賽因

這是一個非常好的數據虛擬化示例(不是 UI 虛擬化):

http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx

盡管它不直接支持 LINQ IQueryable 對象,但您可以按原樣使用此示例。 當然,我現在正在努力改進它以直接使用 IQueryable 對象。 我覺得沒那么難。

哇,200K 行是很多數據。 分頁聽起來是個好主意。 試着決定你想要每頁多少行,比如 50。第一次顯示屏幕時,只顯示前 50。然后讓用戶選擇在頁面之間移動。

盡管如此,排序可能會更棘手。

虛擬化可能是另一種選擇,遺憾的是,我還沒有使用虛擬化。

您的數據網格是否在 Scrollviewer 中? 因為它會渲染整個數據網格(所有行)。 我有一個類似的問題,刪除滾動查看器解決了加載緩慢的問題。

有時您可能只有大約 30 行可見行要加載,並且如果這些行 + 任何列由於每個單元格的數量和復雜性(它是模板,或者它有多少 wpf 元素)而加載起來很昂貴,那么以上都沒有評論真的有所作為。 每一行都需要很長時間才能加載!

有幫助的是交錯或延遲加載 UI 上的每一行,以便用戶看到 ui 正在執行某些操作,而不僅僅是凍結約 10+ 秒.. 為簡單起見,假設數據網格 ItemSource="{Binding Rows} ”,而 Rows 是 IEnumerable,其中 Row 是您創建的某個類:向 Row 添加一個屬性 IsVisible(當然不要忘記提高屬性已更改)

你可以做這樣的事情:

private void OnFirstTimeLoad()
{
    Task.Factory.StartNew(() =>
    {
        foreach (var row in ViewModel.Rows)                                                
        {
            /*this is all you really need, 
              note: since you're on the background thread, make sure IsVisible executes on the UI thread, my utils method does just that*/
              myUtils.ExecuteOnUiThread(() => row.IsVisible = true);

              /*optional tweak: 
              this just forces Ui to refresh so each row repaint staggers nicely*/
              Application.Current.Dispatcher
                         .Invoke(DispatcherPriority.Background, (SendOrPostCallback) delegate { }, null);
         }
       });
}

哦,不要忘記在 XAML 中觸發:

<DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource BoolToVisibility}}"/>
      ........

你應該問的問題是:

  1. 用戶是否正在瀏覽 20 萬行數據?
  2. 多少數據對用戶來說太多了? 可能會提醒用戶查詢返回的行過多,而您正在列出前 1000 行
  3. 如果用戶不查看前 1000 行以外的內容,是否值得您花時間和金錢來編程分頁、數據虛擬化等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM