Help us understand the problem. What is going on with this article?

GridViewの固定列対応

More than 5 years have passed since last update.

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みたいな命名ちょっとアレですね。

wonderful_panda
なのるほどのものでは
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away