10

私は常に WPF DataGrid の読み込みに長い時間がかかり、同様のレポートをオンラインで見つけることができないため、何か間違ったことをしているのではないかと疑っていました。レイアウトの複雑さを追加すると実行が大幅に遅くなるため、今では確信しています。非常に単純なレイアウトでは、DataGrid は瞬時に入力されますが、以下のコードの実行には約 3 秒かかります。

次のコードでは、各セルがどのプロパティにもバインドされておらず、AutoGenerateColumns=False を使用している場合でも、150 行と 11 列を読み込むのに約 3 秒かかります。(十分な RAM を備えた 2 コアの 2.6GHz プロセッサを使用しています)。

ItemsSource プロパティがレイアウトで次のように設定されている場合、ボトルネックが発生します。

<Window x:Class="datagridtest.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">
<Border  Background="LightSteelBlue" CornerRadius="10" Margin="10">
    <ScrollViewer Margin="10" HorizontalScrollBarVisibility="Auto">
        <Grid Margin="10,50,0,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"  />
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />

            </Grid.RowDefinitions>
            <Expander IsExpanded="True" Name="expander1"  Grid.Row="0">
                <Grid>
                    <DataGrid VirtualizingStackPanel.IsVirtualizing="True" AutoGenerateColumns="false" Name="dg" Height="auto" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False">
                        <DataGrid.Columns>
                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>



                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>


                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>



                        </DataGrid.Columns>
                        </DataGrid>
                </Grid>
            </Expander>

            <Expander IsExpanded="true"  Grid.Row="1">
                <Grid>
                    <DataGrid AutoGenerateColumns="True"  Height="auto" />
                </Grid>
            </Expander>

            <Expander IsExpanded="true"    Grid.Row="2">
                <Grid>
                    <DataGrid AutoGenerateColumns="True" Height="auto" />
                </Grid>
            </Expander>
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="121,-42,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click_2" />
        </Grid>
    </ScrollViewer>
</Border>

using System.Collections.ObjectModel;

namespace datagridtest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();


    }

    class row
    {
        public string Name { get; set; }
        public double Age { get; set; }
    }



    private void button1_Click_2(object sender, RoutedEventArgs e)
    {
        ObservableCollection<row> src = new ObservableCollection<row>();

        for (int i = 0; i < 150; i++)
            src.Add(new row { Name = i.ToString(), Age = i / 2 });

        dg.ItemsSource = src;
    }
}
}
4

4 に答える 4

17

この問題は、次のように DataGrid が ScrollViewer 内に埋め込まれている場合にのみ発生します。

<ScrollViewer>
    <Datagrid/>
</ScrollViewer>

この構成により、DataGrid 全体が同時に描画されるため (ScrollViewer のクライアント領域のサイズを正しく設定できるようにするため)、これは理にかなっています。本質的には、独自の ScrollBars を実装する DataGrid の組み込みの仮想化動作をオーバーライドするため、すべてのコンテンツを同時にレイアウトに配置する必要はありません。

つまり、DataGrid には独自の自動スクロール機能があるため、ScrollViewer 内に DataGrid を埋め込む必要はほとんどありません。

于 2010-07-26T18:27:04.847 に答える
7

DataGrid を含む UserControl で同様の問題が発生しました。UserControl を新しいフォームまたは別の UserControl に配置すると、DataGrid を再描画している間、インターフェイスがロックされることがありました (5 秒?)。リサイズも同様。

私はそれを追跡しました

RowDefinition Height="自動"

UserControl を StackPanel に配置すると、同じパフォーマンスの問題も発生しました。カプセル化コンテナのサイズを計算するためにデータグリッド全体を設定する必要がある場合、前述のサイズ変更のバグに大きく関係しているようです。

<UserControl x:Class="ExampleUserControl"
             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="481" d:DesignWidth="773">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" /> <!-- 'AUTO' CAUSES EXTREMELY POOR PERFORMANCE -->
        </Grid.RowDefinitions>

        <Grid Grid.Row="0"> <!-- CHANGING TO STACKPANEL CAUSES EXTREMELY POOR PERFORMANCE -->
            <ContentControl Content="{Binding MyDataGridUserControl}" />
        </Grid>
    </Grid>

</UserControl>

以前のコメントのように、ContentControl の MaxHeight="[whatever]" の設定も機能することを発見しました。画面よりも大きくなる場合があります。

于 2011-09-14T03:33:24.130 に答える
3

すべての行がレイアウト的に生成されているかどうかを確認できますか? 通常、仮想化はそれを妨げ、表示される行のみを生成する必要があります。(列の 1 つでテンプレートを使用してテストし、コンストラクターでカウントします)。WPF が最大の列にサイズ変更しようとするときに DataGrid の正しい幅を判断できない場合、バグが発生します。したがって、最大の幅を持つ行を計算するためにすべての行を生成する必要があります。(最後のものをテストするには - グリッドの代わりにドックパネルに配置 - 左または右にドッキング)

また、VirtualizingStackPanel.VirtualizationMode="Recycling" を試して、使用されているテンプレートをリサイクルできるようにします。

于 2010-07-26T18:02:02.940 に答える