Share via

WPF DataGrid very poor scroll performance

Anonymous
2025-04-03T13:36:55+00:00

Hello,

I need to implement a spreadsheet like control in my WPF app, and all my attempts at using the WPF DataGrid have resulted in very very poor scrolling (it is worst in horizontal than vertical). I have tried:

  • fixed row and column height/width
  • simplified cell styles
  • virtualization
  • disabling automationpeer
  • The WinForms DataGridView, however, it is very slow at selecting cells, since rows become unbound and all that, so it is also not usable for my purpose

and I still get very clumsy scrolling even for a 100x100 grid. I think this is not really usable as it is.

How can I get a fluent spreadsheet in WPF? I have tried several third party controls, but they all have problems too. SyncFusion, for example, takes a lot of time to paste from Excel, Reogrid takes a lot of time to load.. so in the end I do not see any good way of doing this.

Here is my code:

MainWindow.xaml


        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:WpfApp1"

        mc:Ignorable="d"

        Title="MainWindow" Height="1000" Width="1600">

MainWindow.xaml.cs


using System;

using System.Collections.Generic;

using System.Collections.ObjectModel;

using System.ComponentModel;

using System.Diagnostics;

using System.Linq;

using System.Runtime.CompilerServices;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Automation.Peers;

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;

namespace WpfApp1

{

    /// 

    /// Interaction logic for MainWindow.xaml

    /// 

    public partial class MainWindow : Window

    {

        public MainWindowViewModel vm

        {

            get => \_vm;

        }

        private MainWindowViewModel \_vm;

        public MainWindow()

        {

            InitializeComponent();

            \_vm = new MainWindowViewModel();

            this.DataContext = \_vm;

            for (int i = 0; i < vm.Rows[0].Columns.Count; ++i)

            {

                var Col = new DataGridTextColumn();

                var Bind = new Binding();

                Bind.Path = new PropertyPath($"Columns[{i}]");

                Col.Binding = Bind;

                Col.Header = i;

                Col.Width = 80;

                DG.Columns.Add(Col);

            }

        }

        protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()

        {

            return new CustomWindowAutomationPeer(this);

        }

        public class CustomWindowAutomationPeer : FrameworkElementAutomationPeer

        {

            public CustomWindowAutomationPeer(FrameworkElement owner) : base(owner) { }

            protected override string GetNameCore()

            {

                return "CustomWindowAutomationPeer";

            }

            protected override AutomationControlType GetAutomationControlTypeCore()

            {

                return AutomationControlType.Window;

            }

            protected override List

            {

                return new List

            }

        }

    }

    public class ObservableObject : INotifyPropertyChanged

    {

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string name = null)

        {

            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

        }

    }

    public class MainWindowViewModel : ObservableObject

    {

        public class RowData

        {

            public ObservableCollection

            {

                get => \_Columns;

            }

            private ObservableCollection

            public RowData(int iStart)

            {

                var NumCols = 101;

                \_Columns = new ObservableCollection

            }

        }

        public ObservableCollection

        {

            get => \_Rows;

        }

        private ObservableCollection

        public MainWindowViewModel()

        {

            \_Rows = new ObservableCollection

            var NumRows = 101;

            for (int i = 0; i < NumRows; ++i)

            {

                \_Rows.Add(new RowData(i));

            }

        }

    }

}

Windows for home | Other | Apps

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments

1 answer

Sort by: Most helpful
  1. Anonymous
    2025-04-04T06:36:33+00:00

    Hello,Juan Manzanero

    Welcome to posting in the Microsoft Community.

    I can understand the performance issues you're experiencing with the WPF DataGrid, after all, a smooth scrolling experience is critical for spreadsheet applications, and the need to do so becomes even more of an issue when dealing with large amounts of data. At the same time, I've seen your efforts and can very much empathize with you.

    Regarding the code you provided for the WPF DataGrid, there are indeed some optimizations that can be considered to improve performance and fluency, such as the following:

    First, make sure you enable virtualization of the data, which can significantly improve the scrolling experience. Virtualization allows only visible rows and columns to be loaded, thus reducing computation and memory consumption.

    Second, when dynamically generating columns, you may want to consider using DataGridTemplateColumn. this approach helps you to have more flexibility in controlling cell styling and data binding, avoiding unnecessary rendering stress.

    Also, keep an eye on the data binding implementation to make sure that the complexity of the data model doesn't slow down performance. For example, using an ObservableCollection may cause performance issues due to frequent change notifications, especially with large amounts of data. Therefore, simplifying the data structure and reducing the complexity of the initial load is also an effective way to improve responsiveness.

    Finally, it is worth noting that the Microsoft community has specialized forums, such as Microsoft Learn, dedicated to this type of developer issues. It is well worth checking out such forums where many technical support and volunteers will discuss and support your specific code implementation. From there you can copy the question and post it directly to the appropriate forum and section (I have selected the correct forum and section for you):

    Windows - Microsoft Q&A

    I sincerely hope that after contacting the relevant authorities, your issue will be resolved as soon as possible.

    Thank you for your understanding, I really appreciate it!

    I wish you all the best!

    Best Regards,

    Rota|Microsoft Community Support Specialist

    Was this answer helpful?

    0 comments No comments