WPFプログラミング備忘録

WPF DataGridのセルの内容を中央や右寄せで表示と編集をする

WPF

はじめに

この記事ではDataGridのセルのテキストコンテンツを中央や右寄せで表示及び編集する方法について確認します。

セルの内容は何もしないとデフォルトで左寄せになりますが、数値などの場合は右寄せで表示や編集をしたいこともあるでしょう。

今回の開発環境は以下のとおりです。

オペレーティングシステムWindows10 x64
Visual StudioMicrosoft Visual Studio Community 2019 Version 16.11.2
.NET Framewrok4.7.2

DataGridTextColumnクラスの拡張

XAMLで位置を指定できるようにしたいため、DataGridTextColumnクラスの派生クラスを作成することにします。

コードビハインドは以下のとおりです。

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfDataGridAlignmentSample
{
    // アラインメントを指定できるDataGridTextColumnの拡張クラス
    public class DataGridTextColumnWithAlignment : DataGridTextColumn
    {
        // 依存関係プロパティ 垂直方向のアラインメント(デフォルトは中央)
        public VerticalAlignment VerticalAlignment
        {
            get { return (VerticalAlignment)GetValue(VerticalAlignmentProperty); }
            set { SetValue(VerticalAlignmentProperty, value); }
        }

        public static readonly DependencyProperty VerticalAlignmentProperty =
            DependencyProperty.Register("VerticalAlignment", 
                typeof(VerticalAlignment), typeof(DataGridTextColumnWithAlignment), new PropertyMetadata(VerticalAlignment.Center));


        // 依存関係プロパティ 水平方向のアラインメント(デフォルトは左)
        public HorizontalAlignment HorizontalAlignment
        {
            get { return (HorizontalAlignment)GetValue(HorizontalAlignmentProperty); }
            set { SetValue(HorizontalAlignmentProperty, value); }
        }

        public static readonly DependencyProperty HorizontalAlignmentProperty =
            DependencyProperty.Register("HorizontalAlignment", 
                typeof(HorizontalAlignment), typeof(DataGridTextColumnWithAlignment), new PropertyMetadata(HorizontalAlignment.Left));

        protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
            // 未編集状態の時はTextBlock
            var tbl = base.GenerateElement(cell, dataItem) as TextBlock;

            if (tbl != null)
            {
                tbl.HorizontalAlignment = this.HorizontalAlignment;
                tbl.VerticalAlignment = this.VerticalAlignment;
                return tbl;
            }
            
            throw new NullReferenceException();
        }

        protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        {
            // 編集状態の時はTextBox
            var tb = base.GenerateEditingElement(cell, dataItem) as TextBox;

            if (tb != null)
            {
                tb.HorizontalAlignment = this.HorizontalAlignment;
                tb.VerticalAlignment = this.VerticalAlignment;
                return tb;
            }

            throw new NullReferenceException();
        }
    }
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class Person
    {
        public string ID { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        
        public Person(string ID, string LastName, string FirstName)
        {
            this.ID = ID;
            this.LastName = LastName;
            this.FirstName = FirstName;
        }
    }
    public class PersonCollection
    {
        private List<Person> _people = new List<Person>();
        public List<Person> People
        {
            get { return _people; }
        }
        public PersonCollection()
        {
            _people.Add(new Person("210000", "山田", "太郎"));
            _people.Add(new Person("210001", "鈴木", "花子"));
            _people.Add(new Person("210002", "畠山", "銀次"));
            _people.Add(new Person("210003", "青木", "健一"));
            _people.Add(new Person("210004", "多田野", "章宏"));
        }
    }
}

VerticalAlignmentとHorizontalAlignmentという名称の依存関係プロパティを実装します。

また、セルの状態が未編集状態のときと編集状態のときのために、それぞれGenerateElementメソッドとGenerateEditingElementメソッドをオーバーライドします。

表示するだけならGenerateEditingElementメソッドをオーバーライドする必要はありませんが、オーバーライドしていないと編集時に左寄せになってしまいます。

XAMLファイルでのDataGridの定義

XAMLファイルは以下のとおりです。

<Window x:Class="WpfDataGridAlignmentSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfDataGridAlignmentSample"
        Title="MainWindow" Height="250" Width="400">
    <Window.Resources>
        <!-- PersonCollectionクラスのインスタンス生成 -->
        <local:PersonCollection x:Key="objPersonCollection" />
    </Window.Resources>
    <Grid DataContext="{StaticResource objPersonCollection}">
            <DataGrid x:Name="MyDataGrid"
                  Grid.Row="0"
                  ItemsSource="{Binding People}"
                  AutoGenerateColumns="False" 
                  CanUserSortColumns="False" 
                  CanUserAddRows="False"
                  SelectionMode="Single" 
                  SelectionUnit="Cell">
                
                <DataGrid.ColumnHeaderStyle>
                    <Style TargetType="DataGridColumnHeader">
                        <Setter Property="Background" Value="DeepPink"/>
                        <Setter Property="Foreground" Value="White"/>
                        <Setter Property="FontWeight" Value="Bold"/>
                        <Setter Property="BorderThickness" Value="0,0,1,1"/>
                        <Setter Property="BorderBrush" Value="Black"/>
                        <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        <Setter Property="VerticalContentAlignment"   Value="Center"/>
                    </Style>
                </DataGrid.ColumnHeaderStyle>
                <DataGrid.Columns>
                    <local:DataGridTextColumnWithAlignment Header="社員番号" Binding="{Binding ID}" HorizontalAlignment="Right" Width="100" CanUserSort="False" />
                    <local:DataGridTextColumnWithAlignment Header="姓" Binding="{Binding LastName}" HorizontalAlignment="Center" Width="120" IsReadOnly="True" CanUserSort="False" />
                    <local:DataGridTextColumnWithAlignment Header="名" Binding="{Binding FirstName}" HorizontalAlignment="Center" Width="*" IsReadOnly="True" CanUserSort="False" />
                </DataGrid.Columns>
            </DataGrid>
    </Grid>
</Window>

確認のために社員番号は右寄せで編集可能にし、名前は中央に表示し読み取り専用にしました。

また備忘録として列ヘッダーを装飾しています。

プログラムをビルドして実行すると以下のウィンドウが表示されます。

行の高さを広げてみます。

垂直方向はデフォルトの中央に表示されることがわかります。

最後に社員番号を編集状態にしてみます。

右寄せの状態で編集できることがわかります。

今回はDataGridのセルのテキストコンテンツを中央や右寄せで表示及び編集する方法について確認しました。

以上です。

コメント