LoginSignup
10
8

More than 5 years have passed since last update.

GridViewの固定列対応

Posted at

WPFのListViewやDataGridには列を固定する機能が用意されていないらしい。
Excelでいうところの「ウインドウ枠の固定」、WinFormsなら DataGridViewColumn.Frozen = True にあたる機能。

StackOverflowにも質問が上がってるけど、回答としては「ListView2つ並べればいいんじゃねーの」とのこと。
それもちょっとなあという感じ。

必要になりそうなので、ItemsControlの勉強をかねて作ってみた。
https://github.com/wonderful-panda/playground.wpf

サンプル

こんな感じのアレとアレで、

MainViewModel.cs
public class File
{
    public string Name { get; private set; }
    public string Path { get; private set; }
    public long Size { get; private set; }
    public DateTime LastWriteTime { get; private set; }
    public File(FileInfo fi)
    {
        this.Name = fi.Name;
        this.Path = System.IO.Path.GetDirectoryName(fi.FullName);
        this.Size = fi.Length;
        this.LastWriteTime = fi.LastWriteTime;
    }
}

public class MainWindowViewModel
{
    public ObservableCollection<File> Files { get; private set; }
    public MainWindowViewModel()
    {
        var directory = new DirectoryInfo(Environment.CurrentDirectory);
        this.Files = new ObservableCollection<File>(directory.GetFiles().Select(fi => new File(fi)));
    }
}
MainWindow.xaml
<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:Test"
        xmlns:c="clr-namespace:Playground.Controls;assembly=Playground.Controls"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <l:MainWindowViewModel x:Key="viewmodel" />
    </Window.Resources>
    <Window.DataContext>
        <Binding Source="{StaticResource viewmodel}" />
    </Window.DataContext>
    <Grid>
        <c:GridViewEx ItemsSource="{Binding Files}">
            <c:GridViewEx.FrozenColumns>
                <GridViewColumnCollection>
                    <GridViewColumn Header="ファイル名"
                                    DisplayMemberBinding="{Binding Name}" />
                </GridViewColumnCollection>
            </c:GridViewEx.FrozenColumns>
            <c:GridViewEx.NormalColumns>
                <GridViewColumnCollection>
                    <GridViewColumn Header="サイズ"
                                    DisplayMemberBinding="{Binding Size}" />
                    <GridViewColumn Header="更新日時"
                                    DisplayMemberBinding="{Binding LastWriteTime, StringFormat='yyyy/MM/dd HH:mm:ss'}"/>
                    <GridViewColumn Header="フォルダ"
                                    DisplayMemberBinding="{Binding Path}" />
                </GridViewColumnCollection>
            </c:GridViewEx.NormalColumns>
        </c:GridViewEx>
    </Grid>
</Window> 

こんな感じになる。
gridviewex-1.png

gridviewex-2.png

説明

やってることは単純で、行ごとに GridViewRowPresenter を2つずつ(固定列用とそれ以外用)配置して、スクロールバーのHorizontalOffset にあわせて左Marginを調節してるだけです。
細かい作りこみはまだ全然甘いですが。

でも GridViewRowPresenterEx みたいなクラスを作ってその中で頑張る方が筋がいい気もする。
関係ないけど~Exみたいな命名ちょっとアレですね。

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8