wpf datagrid渲染性能(自定义网格控件)

时间:2011-07-01 19:04:27

标签: wpf performance datagrid controls

**请参阅以下问题的更新

我正在尝试在我的WPF应用程序中使用数据网格,但我发现性能难以忍受。

我绑定到一个只有100行和15列的数据集,并且任何类型的滚动甚至列宽都会非常缓慢地调整绘图大小。

我记得旧的winforms datagridview在打开单元格边框时表现不佳,但关闭它的wpf对应网格线没有效果。

带网格的窗口:

<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>

我如何填充数据:

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];
    }
}

编辑:

因为我对数据网格没有运气,我确信它有比我现在想要的更多的功能(只显示纯文本和选择数据进行复制/粘贴)我决定尝试工作靠我自己

这将是我第一次使用自定义用户控件,但我已经找到了性能不佳的原因......网格。

如果我为包含行数据的列和堆栈面板编写带有网格分割器的控件,则滚动行是完美的 - 就像我习惯使用良好的'ol winforms datagrid一样。

网格控制代码:

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);

        }
    }

和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>

当我尝试拖动其中一个分割器时,性能非常糟糕,就像标准的WPF数据网格一样。

现在我知道我没有进行任何虚拟化以优化性能或其他任何功能,但使用stackpanels的性能仍然可以轻松提高100倍。

更新我的问题 - 我想知道是否有人对如何处理其他类型的面板中的列有任何想法,这些列将允许列的相同网格划分器类型功能。

任何与自定义面板/网格的良好链接也将非常受欢迎。

1 个答案:

答案 0 :(得分:1)

根据建议here,您可以通过设置“EnableRowVirtualization”和“EnableColumnVirtualization”而不是VirtualizingStackPanel.*属性来获得一些性能提升。

您还可以通过设置固定的列宽来改进它。