XAMLを使わないWPF入門14「Gridコントロール-静的」

コンピュータ

3×3のグリッドを作成してみます。

XAMLで書くと以下のようになります。

<Window x:Class="GridSamp01.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:GridSamp01"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="30" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>

        <Border Grid.Row="0" Grid.Column="0" Background="#1040D0" />
        <Border Grid.Row="0" Grid.Column="1" Background="#2050D0" />
        <Border Grid.Row="0" Grid.Column="2" Background="#3060D0" />

        <Border Grid.Row="1" Grid.Column="0" Background="#4070E0" />
        <Border Grid.Row="1" Grid.Column="1" Background="#5080E0" />
        <Border Grid.Row="1" Grid.Column="2" Background="#6090E0" />

        <Border Grid.Row="2" Grid.Column="0" Background="#70A0F0" />
        <Border Grid.Row="2" Grid.Column="1" Background="#80B0F0" />
        <Border Grid.Row="2" Grid.Column="2" Background="#90C0F0" />

    </Grid>
</Window>

結果は以下のスクリーンショットの用に格子のサイズが異なる9分割されたグリッドが出来上がります。
これはXAMLのコードの

<Grid.ColumnDefinitions>
     <ColumnDefinition Width="*" />
    <ColumnDefinition Width="2*" />
    <ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
    <RowDefinition Height="*" />
    <RowDefinition Height="2*" />
    <RowDefinition Height="30" />
</Grid.RowDefinitions>

の部分で幅や高さを設定していて、添付プロパティになっています。

C#で書くと以下のようになります。

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace NoXAML14Grid;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.Title = "MainWindow";
        this.Width = 800;
        this.Height = 450;

        var grid = new Grid();

        // カラム定義
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30) });

        // 行定義
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2, GridUnitType.Star) });
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });

        // 各セルにBorderと背景色を設定
        string[,] colors = {
            { "#1040D0", "#2050D0", "#3060D0" },
            { "#4070E0", "#5080E0", "#6090E0" },
            { "#70A0F0", "#80B0F0", "#90C0F0" }
        };

        for (int row = 0; row < 3; row++)
        {
            for (int col = 0; col < 3; col++)
            {
                object? obj = new BrushConverter().ConvertFromString(colors[row, col]);
                Brush brush = obj is null ? Brushes.White : (Brush)obj;

                var border = new Border
                {
                    Background = brush
                };
                Grid.SetRow(border, row);
                Grid.SetColumn(border, col);
                grid.Children.Add(border);
            }
        }

        this.Content = grid;
    }
}

C#では幅や高さの添付プロパティの定義は以下のようになりました。

// カラム定義
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30) });

// 行定義
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });

特にXAMLでは
<ColumnDefinition Width="2*" />
の部分が、C#では
Width = new GridLength(2, GridUnitType.Star)
となっており、*が欧米人には星(Star)に見えると思うと文化の違いを感じます。

GridUnitTypeは以下の3種類が有るようです。

GridUnitType.Star … XAMLの*で全体に対する割合。命名するならStarよりRatioが妥当?
GridUnitType.Auto … XAMLのAuto
GridUnitType.Pixel(デフォルト) … XAMLの値指定(ピクセル)

C#のコードが長めな感じはしますが、ループがかけるので、Grid数が多くなるとC#の方がコンパクトなコードになるのでは無いかと予想します。

コメント