PR

[C#][WPF]DataGridが画面サイズを超えてしまう!スクロールバーが表示されない(汗

C#

DataGridを使ってデータを一覧表示させる場合、全てのデータを確認するためにはスクロールバーが必要ですよね。

でも、なぜか一覧にスクロールバーは表示されず、ウィンドウサイズを越えて大きくなってしまう。

今回はスクロールバーを表示させる方法を解説します。

そして、ページの最後にはDataGridにスクロールバーとセットで設定した方がよいおまじないをご紹介します。

スクロールバーを表示する

DataGridに対して、”Scroll”と入力した場合のインテリセンス(自動補完機能)は下図のように出ます。

WPFには、『ScrollBar』と『ScrollViewer』という似たようコントロールが用意されています。

違いは何かというと、ScrollViewerは、ScrollBarをラップ・拡張した機能強化版です。特に指定がない限りScrollViewerを使っておけば良いです。

横スクロールバー

横方向のスクロールバーは、「HorizontalScrollBarVisibility」プロパティで設定します。
プロパティの値については、後述します。

縦スクロールバー

縦方向のスクロールバーは、「VertivalScrollBarVisibility」プロパティで設定します。
プロパティの値については、後述します。

プロパティの値について

縦・横スクロールの画像を見比べてもらうと分かると思いますが、プロパティの値は縦も横も同じです。

Autoコンテンツを全て表示できない場合に、スクロールバーを表示します。
Disabledコンテンツが全て表示できない場合でも、スクロールバーを表示しません。
必要に応じてコンテンツの幅や高さがコンテナのサイズまで切り詰められます。
Hidden コンテンツが全て表示できない場合でも、スクロールバーを表示しません。
コンテンツは切り詰められません。
Visibleスクロールバーを常に表示します。

DataGridがウィンドウサイズを越えてしまう問題

DataGridに対して、ObservableCollectionのデータをバインディングして、スクロールバーも設定して、いざ表示してみたら画面領域を超えてしまい、スクロールバーも操作できない。

こんな罠に引っかかっていませんか?

原因

この問題は、親のビジュアルツリーに原因がある可能性が高いです。

DataGridの親ツリーに『StackPanel』や『Canvas』などを使っていませんか?

実は、このコントロールは、子ツリーに合わせて無限に拡張されるように制御されているんです。

そのうえ、DataGridも全ての項目に合わせて拡大してしまうため、スクロールバーは表示されないでウィンドウサイズを越えて大きくなってしまうのです。

対処方法

いくつか対処方法はあります。

  • 高さを固定してしまう。
  • 親ツリーを別のものに変える

などなど。

オススメの方法は、親ツリーを DockPanel に変更する方法です。
イメージとしては、このようなツリーになります。

<DockPanel>
    <DataGrid
        ScrollViewer.HorizontalScrollBarVisibility="Visible"
        ScrollViewer.VerticalScrollBarVisibility="Visible">

    </DataGrid>
</DockPanel>

この場合でも同様の注意が必要です。

以下のように親の親が StackPanel になっていると、結局子ツリーに合わせて拡大してしまうため効果がありません。親の親も DockPanel に変えるなど検討してみてください。

<StackPanel>
    <DockPanel>
        <DataGrid
            ScrollViewer.HorizontalScrollBarVisibility="Visible"
            ScrollViewer.VerticalScrollBarVisibility="Visible">

        </DataGrid>
    </DockPanel>
</StackPanel>

パネルを上手に使いこなせると、モニターサイズに合わせて自動でレイアウトが調整されるような画面が作れるようになります。

Try & Error でチャレンジしながら覚えていきましょう。

おまじない

DataGridを既に使ったことのある方は、経験されたことがあるかも知れませんが、データ量が多くなるとDataGridの描画は重くなります。

原因は、DataGridがデータを全て描画しようとするからです。

どういうことかというと、DataGridでコントロール上に見えていない範囲にあるデータ(スクロールしないと見えてこないデータ)も描画してしまうのです。

データが少なければ、影響も小さいため良いのですが、データが多くなると、その分メモリ使用量も増え、パフォーマンスに影響してしまうのです。

これを回避するためのおまじないがあります。

さっそくコードを示します。

<DataGrid
    ScrollViewer.HorizontalScrollBarVisibility="Auto"
    ScrollViewer.VerticalScrollBarVisibility="Auto"
    EnableColumnVirtualization="True"
    EnableRowVirtualization="True"
    VirtualizingPanel.IsVirtualizing="True"
    VirtualizingPanel.VirtualizationMode="Recycling">

</DataGrid>

赤文字部分がおまじないです。

『UIの仮想化』と呼ばれています。

画面に表示される分のデータだけ展開しているため、パフォーマンスが軽快になります。

騙されたと思っておまじない試してみてください。

コメント

タイトルとURLをコピーしました