1
votes

**Please see updates to question below

I am trying to use a datagrid in my WPF application but I am finding the performance to be unbearable.

I am binding to a dataset with only 100 rows and 15 columns and any sort of scrolling or even column width resizing paints EXTREMELY slowly.

I recall the old winforms datagridview had poor performance when cell borders were turned on, but turning off gridlines in it's wpf counterpart has no effect.

The Window with the grid:

<Window x:Class="GridPerformanceTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="True" EnableColumnVirtualization="True" EnableRowVirtualization="True"
              VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" Background="{x:Null}" 
              BorderBrush="{x:Null}" IsSynchronizedWithCurrentItem="False" BorderThickness="0" RowHeight="15" 
              GridLinesVisibility="None" HorizontalGridLinesBrush="{x:Null}" VerticalGridLinesBrush="{x:Null}" ColumnHeaderHeight="15"/>
</Grid>

How I am populating my data:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataSource source = new DataSource();

        DataSet ds = new DataSet();
        ds.Tables.Add(source.Execute("select * from tbl_users"));

        this.DataContext = ds.Tables[0];
    }
}

EDIT:

So because I have had no luck with the datagrid, which I'm sure has many more features than what I am looking for right now (simply display plain text and select data for copy/paste) I decided to try and work on my own.

This will be my first shot at a custom user control, but I have already found the source of the poor performance...the grid.

If I write a control with grid splitters for my columns and stackpanels that contain my row data, scrolling through the rows is flawless - like I was used to with the good 'ol winforms datagrid.

Grid control code:

public partial class CustomGridControl : UserControl
{
    public CustomGridControl()
    {
        InitializeComponent();

        for (int i = 0; i < 20; i++)
        {
            ColumnDefinition col = new ColumnDefinition();
            col.Width = new GridLength(75);
            _rootGrid.ColumnDefinitions.Add(col);

            StackPanel pnl = new StackPanel();
            pnl.Orientation = Orientation.Vertical;

            for (int x = 0; x < 1000; x++)
            {
                TextBlock blk = new TextBlock();
                blk.Foreground = Brushes.Black;
                blk.Text = "Row: " + x.ToString() + " Col: " + i.ToString();

                pnl.Children.Add(blk);
            }

            Grid.SetColumn(pnl, i);
            _rootGrid.Children.Add(pnl);

            GridSplitter splitter = new GridSplitter();
            splitter.Width = 2;
            splitter.BorderBrush = Brushes.Black;

            Grid.SetColumn(splitter, i);
            Grid.SetRowSpan(splitter, 1000);

            _rootGrid.Children.Add(splitter);

        }
    }

And the XAML:

<UserControl x:Class="CustomGrid.CustomGridControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<Grid >
    <ScrollViewer>
        <Grid x:Name="_rootGrid" Background="Aqua"/>
    </ScrollViewer>
</Grid>

When I try and drag one of the splitters, the performance is horrible, just as with the standard WPF datagrid.

Now I know I am not doing any virtualization to optomize performance or anything but the performance with stackpanels is still easily 100x better.

To update my question - I would like to know if anyone has any ideas of how to handle the columns in another type of panel that would allow the same gridsplitter type functionality for the columns.

Any good links to custom panels/grids would be much appreciated as well.

1
What's your question? There's no way to speed up the Microsoft DataGrid, which yes has horrid performance. Are you asking what's a good alternative?Ed Bayiates
Well, I was hoping to speed up the datagrid, actually :p What would be a good option? I have tried using a gridview and the performance is marginally better - I feel as though something or some setting is wrong as these controls are virtually unusable when compared with the datagridview from good 'ol winforms.ChandlerPelhams
There is no way I know of to speed up the Microsoft DataGrid. Exceed's is much faster, as are a few other companies. If you don't need to write the data, a ListView/GridView is a great deal faster (10-20 times).Ed Bayiates
I have tried working with the listview/gridview and noticed some performance increases, but still I felt it was unacceptable. There was still a latency between me moving the scroll bar and the scrolling taking place. Additionally, when resizing the window (grid is set to stretch to window size) it still takes a full second and half to paint. This is my first try at WPF, and I don't understand how anyone can use it with a grid that has this poor of performance when compared to the winforms grid.ChandlerPelhams
A second and a half for a ListView/GridView? That doesn't sound right. How many items are you adding? If it's thousands you want to make sure it's virtualized.Ed Bayiates

1 Answers

1
votes

As suggested here, you can get a bit of a performance improvement by setting 'EnableRowVirtualization' and 'EnableColumnVirtualization' instead of the VirtualizingStackPanel.* properties.

You can also improve it things by setting fixed column widths.