DataGridの特定の列幅を可変で表示する(水平スクロールバー有り)
DataGridで一覧を表示する際、特定の列幅のみ可変で、水平スクロールバー有りで表示したいといったことがあったので、その方法についてです。
コード
以下は、DataGridの3列目を可変にした場合のコードになります。
◆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"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="600">
<Canvas>
<Button Name="Button01" Canvas.Top="5" Canvas.Left="10" Content="表示" Padding="10, 2" Width="50" Click="Button01_Click"/>
<Button Name="Button02" Canvas.Top="5" Canvas.Left="70" Content="クリア" Padding="10, 2" Width="50" Click="Button02_Click"/>
<DataGrid Name="DataGrid01" Canvas.Top="40" Canvas.Left="10" Width="564" Height="300"
AutoGenerateColumns="False" CanUserAddRows="False" AlternatingRowBackground="#f8f8f8"
HeadersVisibility="Column" GridLinesVisibility="None">
<DataGrid.Columns>
<DataGridTextColumn Header="商品名" Binding="{Binding Name}" Width="200"/>
<DataGridTextColumn Header="金額" Binding="{Binding Price}" Width="100"/>
<DataGridTextColumn Header="備考" Binding="{Binding Description}" MinWidth="238" Width="auto"/>
</DataGrid.Columns>
</DataGrid>
</Canvas>
</Window>
MinWidthに最小の列幅を設定し、Width="auto"とすることで、セルの内容によって表示時に列幅が自動で調整され、DataGridの幅を超える場合、水平スクロールバーが表示されるようになります。「HeadersVisibility="Column"」と「GridLinesVisibility="None"」については見栄えのための設定です。
◆MainWindow.cs
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1
{
public partial class MainWindow : Window
{
private int count = 0;
public MainWindow()
{
InitializeComponent();
}
private void Button01_Click(object sender, EventArgs e)
{
var items = Enumerable.Range(1, 20)
.Select(x => new Product { Name = $"商品{x:00}", Price = 100, Description = "備考" })
.ToList();
count++;
if(count % 2 == 0)
{
items[0].Description = "123456789012345678901234567890";
}
DataGrid01.ItemsSource = items;
// 列幅のリセット
DataGrid01.Columns[2].Width = DataGrid01.Columns[2].MinWidth;
DataGrid01.Columns[2].Width = DataGridLength.Auto;
// スクロール位置のリセット(垂直、水平)
DataGrid01.ScrollIntoView(DataGrid01.Items[0], DataGrid01.Columns[0]);
}
private void Button02_Click(object sender, EventArgs e)
{
DataGrid01.ItemsSource = null;
}
}
public class Product
{
public string Name { get; set; }
public int Price { get; set; }
public string Description { get; set; }
}
}
動作確認のため、表示ボタンを押すたびに表示するデータの内容を書き換えています。
また、再表示の際に、そのままでは前回の水平スクロールがそのまま残ってしまうので、データセット後に列幅のリセットを行っています。