WPF 同じ要素を数十個単位で作成する

（備忘録）

### 実現したかった内容
Gridで以下のような列要素を数十個単位で作成したかった。

``` MainWindow.xaml
<Grid Background="#FFE5E5E5">
    <DataGrid Name="testGrid" AutoGenerateColumns="False">
        <DataGrid.Columns>

            <!-- こんな感じの列が数十個ほしい -->
            <DataGridTextColumn  Binding="{Binding testColumnValue}">
                        <!-- IsFaultがtrueのとき赤背景表示 -->
                        <DataGridTextColumn.CellStyle>
                                    <Style TargetType="DataGridCell">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding IsFault}" Value="True">
                                                <Setter Property="Background" Value="Red" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                        </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>

        </DataGrid.Columns>
    </DataGrid>
</Grid>

```

### 実際の実装

カラムの動きとしては
① testColumnValueを表示する
② IsFaultがtrueの時に赤背景となる
というものを達成できればよかったため、以下のようにした。

xaml側でコピー用のカラムを作成。


``` MainWindow.xaml
<Grid Background="#FFE5E5E5">
    <DataGrid Name="testGrid" AutoGenerateColumns="False">
        <DataGrid.Columns>

                <!-- コピー用カラム -->
                <DataGridTextColumn x:Name="OriginalTestColumn" Binding="{Binding testColumnValue}">
                        <!-- IsFaultがtrueのとき赤背景表示 -->
                        <DataGridTextColumn.CellStyle>
                                <Style TargetType="DataGridCell">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding IsFault}" Value="True">
                                                <Setter Property="Background" Value="Red" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                </Style>
                        </DataGridTextColumn.CellStyle>
                </DataGridTextColumn>

        </DataGrid.Columns>
    </DataGrid>
</Grid>

```

ソースで新規カラムを作成し、ヘッダーとバインドを設定。
DataTriggerをコピー用カラムからコピーし設定。
これを必要な数繰り返し、最後にコピー用カラムを削除。

``` MainWindow.xaml.cs
/// <summary>
/// グリッドを初期化
/// </summary>
private void InitializeGrid()
{
    // test1～test100のカラムを作成する
    // オリジナルカラムを検索
    DataGridTextColumn? original = this.FindName("OriginalTestColumn") as DataGridTextColumn;

    for (int i = 1; i <= 100; i++)
    {
        // 新規カラムを作成
        DataGridTextColumn column = new();

        // Headerを設定
        column.Header = "test" + i.ToString();

        // バインドを設定
        column.Binding = new Binding("testColumnValue");

        // 背景色変更トリガをオリジナルからコピー
        column.CellStyle = new Style();
        column.CellStyle.Triggers.Add(original.CellStyle.Triggers[0]);

        // カラムをグリッドに追加
        testGrid.Columns.Add(column);
    }

    // オリジナルカラムを削除
    testGrid.Columns.Remove(original);
}
```

バインドするプロパティは以下のように実装。
作成したカラムがプロパティにアクセスするたびにインデックスをインクリメントし、配列のデータをひとつずつ参照する。

``` MainWindow.xaml.cs

/// <summary> インデックス </summary>
private int testValueIndex { get; set; } = 0;
private int testFaultIndex { get; set; } = 0;

/// <summary> 配列 </summary>
public (string tvalue, bool tfault)[] testData { get; }

/// <summary> 表示用プロパティ </summary>
public string testColumnValue
{
    get
    {
        string rtnvalue = "";

        // 配列外参照を制限
        if(testValueIndex < testData.Length) rtnvalue = testData[testValueIndex].tvalue;
                
        // インデックスを加算
        testValueIndex++;
        if (testValueIndex >= 100) testValueIndex = 0;

        return rtnvalue;
    }
}

/// <summary> 障害プロパティ </summary>
public bool IsFault
{
    get
    {
        bool rtnvalue = false;

        // 配列外参照を制限
        if (testFaultIndex < testData.Length) rtnvalue = testData[testFaultIndex].tfault;

        // インデックスを加算
        testFaultIndex++;
        if (testFaultIndex >= 100) testFaultIndex = 0;

        return rtnvalue;
    }
}
```

### 備考
DataTriggerをソース上で設定する手順がわからず、コピー用カラムを作成するような形をとった。
多分どうにかすればできるはずだが、時間がなく断念。