3

問題は、DataGrid または ItemsControl を分割してコントロールを小さなチャンクにレンダリングし、コントロール全体をレンダリングするために UI が 15 秒間ブロックされないようにすることはできますか?

render は別のスレッドで作成されているため、実際には UI をブロックしていないと思いました。


My ItemsControl は、いくつか (最大で 20 個まで) のデータグリッドをホストします。最大 100 行を含めることができるものもあれば、1 行だけ短いものもあります。アイテムの基礎となる ObservableCollection を埋めるときに、大きな遅延が発生しています。

これが私がやろうとしていることの簡単な説明です:

  1. UIThread では、いくつかのデータを選択します。
  2. このデータは VM 2.5 に送信されます。VM は、ItemsControl にテンプレートをロード中のプレースホルダー画面に変更させる IsBusy フラグを設定します。
  3. VM は BackgroundWorker でいくつかの DB 要求を行います
  4. VM BackgroundWorker Dispatcher.DataViews を VM の ObservableCollection に呼び出して、一度に 1 つの DataView に戻します この時点までは、すべてうまく機能します: UI が責任を負い、プログレスバーの更新などを行っていますが、その後:
  5. VM シグナル: IsBusy=false => ItemsControl がテンプレートを元の状態に戻します
  6. UIが ~15 秒間ハングして、ItemsControl 内のすべての DataGrid をレンダリングします (CPU の CPU 使用率が高いことがわかります)

ここにいくつかのコードがあります:

XAML (これがコンテンツをスクロール可能にする唯一の方法であることがわかったため、ScrollViewer 内に ItemsControl を配置しました。):

<ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Column="1" Grid.Row="0" 
                      VirtualizingStackPanel.IsVirtualizing="True"
                      VirtualizingStackPanel.VirtualizationMode="Recycling">
    <ItemsControl 
                  DataContext="{Binding Source={StaticResource TerminalMaskVM}}"
                  VirtualizingStackPanel.IsVirtualizing="True"
                  VirtualizingStackPanel.VirtualizationMode="Recycling"
                  Style="{StaticResource LoadingControl}"
                  ItemsSource="{Binding Source={StaticResource TerminalMaskVM}, Path=TerminalMasks}"
                  x:Name="MaskContainer">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <DockPanel
                    VirtualizingStackPanel.IsVirtualizing="True"
                    VirtualizingStackPanel.VirtualizationMode="Recycling"
                    IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="DockPanel.Dock" Value="Top"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander IsExpanded="True" Header="{Binding MaskTableName}">
                        <gui:DataGrid ItemsSource="{Binding MaskTable}"
                                      EnableColumnVirtualization="True"
                                      VirtualizingStackPanel.IsVirtualizing="True"
                                      VirtualizingStackPanel.VirtualizationMode="Recycling"
                         ...columns definitions, etc..
                         ...closing tags here

問題を幅広く検索し、次のことを試しました。

  1. VirtualizingStackPanel.IsVirtualizing="True" および VirtualizingStackPanel.VirtualizationMode="Recycling" を指定
  2. ItemsControl コンテナを DockPanel に切り替えようとしました
  3. RowHeight と列の幅を固定値に設定します

レンダリング時間には影響しませんでした。

4

0 に答える 0