FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

仮想化したまま物理スクロールする(.NET 4.5)

 ListBoxは規定だと仮想化された論理スクロールになっています。
 .NET Framework 4.5からListBox等で仮想化したまま物理スクロールができるようになりました。
 コレクションをバインディングして表示するときは仮想化は必須です。
 仮想化をOffにした場合かなりUIが重くなります。アイテム数が10個くらいならなんとかなりますが、百個くらいになると目に見えて遅くなります。
 .NET Framework 4.0までは仮想化したまま物理スクロールしたい場合は、自分でListBoxをカスタマイズしたコントロールを作る必要がありましたが、.NET 4.5からはプロパティをいじるだけで仮想化したまま物理スクロールできるようになりました。
<Window x:Class="PhysicalScroll.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:v="clr-namespace:PhysicalScroll.Views"
        xmlns:vm="clr-namespace:PhysicalScroll.ViewModels"
        Title="MainWindow" Height="350" Width="525">
    
    <Window.DataContext>
        <vm:MainWindowViewModel/>
    </Window.DataContext>
   
    <Window.Resources>
        <DataTemplate x:Key="template">
            <Border BorderBrush="Black" BorderThickness="1" Width="100" Height="50">
                <TextBlock Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </DataTemplate>
    </Window.Resources>
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        
        <GroupBox Grid.Column="0" Header="規定のListBox">
            <ListBox ItemsSource="{Binding Items}"
                     ItemTemplate="{StaticResource template}"/>
        </GroupBox>
        
        <GroupBox Grid.Column="1" Header="仮想化Onで物理スクロール">
            <ListBox ItemsSource="{Binding Items}"
                     ItemTemplate="{StaticResource template}"
                     VirtualizingPanel.ScrollUnit="Pixel"/>

        </GroupBox>
        
        <GroupBox Grid.Column="2" Header="仮想化Offで物理スクロール">
            <ListBox ItemsSource="{Binding Items}"
                     ItemTemplate="{StaticResource template}"
                     ScrollViewer.CanContentScroll="False"/>

        </GroupBox>
    </Grid>
</Window>
 このサンプルコードでは同じデータ(数値リスト)を論理スクロールと物理スクロールで表示しています。
 実行すると以下の様になります。
物理スクロール
 左は規定のListBoxを使用した場合です。
 この状態だと仮想化On + 論理スクロールになっています。そのため、スクロールした場合表示している要素ごとにスクロールが行われます。表示要素に高さがある場合は、スクロールしているとどこまでスクロールしたかが解りにくくなります。
 真ん中のListBoxは仮想化したまま物理スクロールさせた場合です。
 物理スクロールなのでピクセル単位でスクロールができます。
 また、仮想化されているのでアイテム数が多いコレクションとバインディングしても重くなりません。
 右側のListBoxは仮想化せずに物理スクロールさせた場合です。(.NET 4.0までの方法です)
 物理スクロールですが、仮想化されていないのでアイテム数が多いとかなり重くなります。

 .NET 4.0までの場合はScrollViewer.CanContentScrollをfalseにすることで物理スクロールになりました。(ただし仮想化はOffになります。)
 .NET 4.5では、VirtualizingPanel.ScrollUnitをPixelにすることで、仮想化したまま物理スクロールすることができるようになります。
 この時注意する点は、ScrollViewer.CanContentScrollはTrueのままにしておく必要があることです。
 プロパティ名を見るとFalseにする必要がある様に思えますが、これをFalseにすると仮想化がOffになってしまいます。
 仮想化されているかどうかはWPF Inspector等のツールを使うことで確認できます。
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

カレンダー
11 | 2018/12 | 01
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
全記事表示リンク

全ての記事を表示する

カテゴリ
タグリスト

月別アーカイブ
11  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09 
最新記事
リンク
最新コメント
検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。