DataGridのヘッダー結合

今回はC#のWPFでDataGridのヘッダー結合にポンコツ2人組が挑戦してみました。 WPFのDataGridでヘッダーを結合することは、標準の機能として提供されていませんが、 カスタムヘッダーテンプレートを使用してヘッダーを結合できます。 開発環境はVisualStudio2019を使用しています。 C#初心者が制作したものなのでいろいろとおかしい部分が多いと思います。プログラムを流用する際は適宜修正してください。

※この記事は2023/09/04時点の情報です。

MainWindow.xaml
カスタムヘッダーテンプレートを使用する場合、 データをヘッダーテンプレートにプロパティを直接バインドすることができます。 明細部分のデータをバインドする方法は、通常の方法と同じです。 明細部分のデータは、各列のデータバインディングを設定することによってバインドされます。

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding SampleDataCollection}">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="Header1" Margin="5" Width="100"/>
                                <TextBlock Text="Header2" Margin="5" Width="210"/>
                                <TextBlock Text="Header3" Margin="5" Width="100"/>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.HeaderTemplate>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                            <!-- ここで明細部分のデータをバインド -->
                                <TextBlock Text="{Binding Property1}" Width="100" Margin="5"/>
                                <TextBlock Text="{Binding Property2}" Width="100" Margin="5"/>
                                <TextBlock Text="{Binding Property3}" Width="100" Margin="5"/>
                                <TextBlock Text="{Binding Property4}" Width="100" Margin="5"/>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <!-- 他の列を追加 -->
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

MainWindow.xaml.cs
サンプルデータを作成し、それをWPFのDataGridにバインドします。

using System.Collections.ObjectModel;
using System.Windows;

namespace WpfApp1
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public ObservableCollection SampleDataCollection { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            SampleDataCollection = new ObservableCollection
        {
            new SampleData { Property1 = "Data 1-1", Property2 = "Data 1-2", Property3 = "Data 1-3" , Property4 = "Data 1-4" },
            new SampleData { Property1 = "Data 2-1", Property2 = "Data 2-2", Property3 = "Data 2-3" , Property4 = "Data 2-4"},
            new SampleData { Property1 = "Data 3-1", Property2 = "Data 3-2", Property3 = "Data 3-3" , Property4 = "Data 3-4" }
        };

            DataContext = this;
        }
    }
}

HeaderData.cs
ヘッダーにバインドしているクラスになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp1
{
    class HeaderData
    {
        public string Header1 { get; set; }
        public string Header2 { get; set; }
        public string Header3 { get; set; }
    }
}

SampleData.cs
明細にバインドしているクラスになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp1
{
    public class SampleData
    {
        public string Property1 { get; set; }
        public string Property2 { get; set; }
        public string Property3 { get; set; }
        public string Property4 { get; set; }
    }
}

実行すると、とりあえず上手くDataGridのヘッダーが結合されているかのように見えます。 しかしWEBなどに比べると、ヘッダー行を結合させたいだけなのに意外と面倒な印象を受けますね・・・

管理人情報