4

DataGridにバインドされた .NET 4.0 WPF を使用していますObservableCollection<T>。コレクションには、1 秒間に数回、行が追加および削除されています。は/ /DataGridに含まれています。TabControlTabItemGrid

表示したままにしておく限り、多かれ少なかれ問題なく動作します。アプリの別のタブに移動し、数分後に戻ると、UI スレッドが 30 秒間ロックされます (合計約 1200 行で、そのうち約 40 行が画面に表示されます)。すべての行データは既にメモリ内にあるため、I/O はありません。すべてのバインドされたプロパティは単純な文字列、数値、または日付のいずれかであるか、それらを作成するロジックは非常に単純です。計算に複雑なことや時間のかかることは何もありません。

行数が数百を超える場合、並べ替える新しい列を選択するのに非常に時間がかかります。新しい行の追加も遅いようです。別のタブに切り替えてからすぐに戻ると、グリッドがすぐに再表示されます。

ウィンドウのサイズ変更は正常に実行されます。

スクロールのパフォーマンスは最初は遅いですが、グリッドが完全に読み込まれると取得します。それは決して素晴らしいことではありません。がないScrollView.CanContentScroll="False"と、スクロールが遅くて使い物になりません。代わりに使用IsDeferredScrollingEnabled="True"すると、ユーザーがスクロールバーを離した後、レンダリングで 10 秒以上の遅延が発生します。これは、依然として許容できないユーザー エクスペリエンスです。

17 あり ますDataGridTextColumns。列のいくつかは customStringFormatsを使用していますが、複雑なことは何もありません。いいえTypeConverters

Visual Studio パフォーマンス ツール/プロファイラーは役に立ちませんでした。これは、比較的単純で簡単なセットアップのようです。パフォーマンスを改善する方法についての提案をいただければ幸いです。

また、なぜこんなに遅いのか知りたいです。

<DataGrid x:Name="MyGrid" AutoGenerateColumns="False" Margin="3,35,3,20" VerticalContentAlignment="Center" Width="Auto" 
                          FontSize="12" FontFamily="Consolas" ScrollViewer.CanContentScroll="False"
                          CanUserResizeRows="False" AlternationCount="2" AlternatingRowBackground="#FFE3F0FF"
                          VirtualizingStackPanel.VirtualizationMode="Recycling" IsReadOnly="True">
    <DataGrid.Columns>
        <DataGridTextColumn Header="XX" Binding="{Binding Path=XX}" />
        <DataGridTextColumn Header="YY" Binding="{Binding Path=YY, StringFormat={}{0:0.0}}">
            <DataGridTextColumn.ElementStyle>
                <Style>
                    <Setter Property="TextBlock.TextAlignment" Value="Right" />
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
        . . .
    </DataGrid.Columns>
</DataGrid>
4

2 に答える 2

4

を削除しScrollViewer.CanContentScroll = "False"ます。WPF DataGrid のデフォルトの UI 仮想化サポートを無効にします。

こちらの回答を参照してくださいPhysical scrolling disable UI Virtualization

答えから -

"ScrollViewer は現在、2 つのスクロール モードを許可しています: スムーズなピクセル単位のスクロール (CanContentScroll = false) または個別の項目単位のスクロール (CanContentScroll = true)。現在、WPF は項目単位でスクロールする場合にのみ UI 仮想化をサポートしています。ピクセルベースのスクロールは「物理スクロール」とも呼ばれ、アイテムベースのスクロールは「論理スクロール」とも呼ばれます。

アップデート

スクロールバーをドラッグしているときにスムーズな操作が必要な場合は、IsDeferredScrollingEnabledを設定できます。trueドラッグ操作中にすべてのアイテムを作成するのではなく、スクロールバーのつまみを離したときにのみビュー内のアイテムをレンダリングします。

<DataGrid ScrollViewer.IsDeferredScrollingEnabled="True"/>

また、 MSDNからのこのリンクが役立つ場合があります。

于 2012-11-24T13:33:55.407 に答える
0

タブアイテムを切り替えるときに、タブアイテムの状態が永続しないというTabControlの問題を調査することをお勧めします。

TabControlには特定の動作があります。タブ項目が選択解除されると、そのコンテンツは破棄され、タブ項目が再度選択されたときに再作成する必要があります。つまり、DataGrid全体とその表示されているすべてのDataGridCellを再作成する必要があります。

「WPFTabControlの永続的なビジュアルツリー」または「WPFTabControlの永続的な状態」の場合はGoogleだけです。

于 2012-12-02T20:24:50.023 に答える