J D
J D

Reputation: 48687

Improve WPF DataGrid's scrolling performance

Here is a simple DataGrid benchmark:

open System.Windows

let mutable i = 0
let timer = System.Diagnostics.Stopwatch.StartNew()

[<System.STAThreadAttribute>]
do
  let grid = Controls.DataGrid()
  grid.AutoGenerateColumns <- false
  for i in 1..50 do
    let c = Controls.DataGridTextColumn()
    c.Binding <- Data.Binding()
    c.Header <- string i
    grid.Columns.Add c
  grid.ItemsSource <- Array.init 1000 string
  let window = Window(Content=grid)
  window.WindowState <- WindowState.Maximized
  Media.CompositionTarget.Rendering.Add(fun _ ->
    i <- i + 38
    grid.ScrollIntoView grid.Items.[i % 1000]
    window.Title <- sprintf "%gfps" (float i / timer.Elapsed.TotalSeconds / 38.0)
    if i > 10000 then
      i <- 1
      timer.Restart())
  Application().Run window
  |> ignore

I get awful performance from this (6 frames/sec on a 4x 3.4GHz Intel Core i7). How can this be optimized?

I found some recommendations on the web but none of them make any significant difference:

  grid.EnableColumnVirtualization <- true
  grid.EnableRowVirtualization <- true
  grid.ColumnWidth <- Controls.DataGridLength 27.0
  grid.RowHeight <- 18.0
  ...
    if i=0 then
      let border = Media.VisualTreeHelper.GetChild(grid, 0) :?> Controls.Border
      let scroll = border.Child :?> Controls.ScrollViewer
      scroll.IsDeferredScrollingEnabled <- true

Upvotes: 1

Views: 525

Answers (1)

Fraser Muir
Fraser Muir

Reputation: 486

I'm sure you have already considered this, but have you made sure you are not using a debugger, as turning it off dramatically improves performance

Edit

Okay, why don't you try to use a dispatch timer instead. This could run on a separate thread, thus theoretically improving performance

Upvotes: 1

Related Questions