FlexGrid for WPF
同じ値を持つセルをマージする(制限付き)
基本操作 > マージ > 同じ値を持つセルをマージする(制限付き)

グリッドのAllowMergingプロパティをAllに設定して、IMergeManagerインタフェースを実現することでマージ動作をカスタマイズすることが用意されています。たとえば、セルの上にあるセルもマージされる場合の動作は以下のRestrictRowsメソッドのように実現できます。それと同じように、左にあるセルもマージする場合、以下のRestrictColsメソッドのようにに実現できます。

【実行例】

サンプルコードは次のようになります。

コードのコピー
'左にあるセルもマージする場合
Private Sub InitializeRestrictCols()
    For i As Integer = 0 To 1
        _restrictColsflex.Columns.Add(New C1.WPF.FlexGrid.Column())
    Next
    For i As Integer = 0 To 3
        _restrictColsflex.Rows.Add(New C1.WPF.FlexGrid.Row())
    Next
    ' データを設定する場合
    _restrictColsflex(0, 0) = "関東"
    _restrictColsflex(1, 0) = "関東"
    _restrictColsflex(2, 0) = "関西"
    _restrictColsflex(3, 0) = "関西"
    _restrictColsflex(0, 1) = "北海道"
    _restrictColsflex(1, 1) = "北海道"
    _restrictColsflex(2, 1) = "北海道"
    _restrictColsflex(3, 1) = "北海道"

    _restrictColsflex.AllowMerging = AllowMerging.All
    _restrictColsflex.MergeManager = New RestrictColsMergeManager()

End Sub

'上にあるセルもマージする場合
Private Sub InitializeRestrictRows()
    For i As Integer = 0 To 3
        _restrictRowsflex.Columns.Add(New C1.WPF.FlexGrid.Column())
    Next
    For i As Integer = 0 To 1
        _restrictRowsflex.Rows.Add(New C1.WPF.FlexGrid.Row())
    Next
    _restrictRowsflex.AllowMerging = AllowMerging.All
    _restrictRowsflex.MergeManager = New RestrictRowsMergeManager()
    _restrictRowsflex(0, 0) = "関東"
    _restrictRowsflex(0, 1) = "関東"
    _restrictRowsflex(0, 2) = "関西"
    _restrictRowsflex(0, 3) = "関西"
    _restrictRowsflex(1, 0) = "北海道"
    _restrictRowsflex(1, 1) = "北海道"
    _restrictRowsflex(1, 2) = "北海道"
    _restrictRowsflex(1, 3) = "北海道"
End Sub
コードのコピー
//左にあるセルもマージする場合
private void InitializeRestrictCols()
{
    for (int i = 0; i < 2; i++)
    {
        _restrictColsflex.Columns.Add(new C1.WPF.FlexGrid.Column());
    }
    for (int i = 0; i < 4; i++)
    {
        _restrictColsflex.Rows.Add(new C1.WPF.FlexGrid.Row());
    }
    // データを設定する場合
    _restrictColsflex[0, 0] = "関東";
    _restrictColsflex[1, 0] = "関東";
    _restrictColsflex[2, 0] = "関西";
    _restrictColsflex[3, 0] = "関西";
    _restrictColsflex[0, 1] = "北海道";
    _restrictColsflex[1, 1] = "北海道";
    _restrictColsflex[2, 1] = "北海道";
    _restrictColsflex[3, 1] = "北海道";

    _restrictColsflex.AllowMerging = AllowMerging.All;
    _restrictColsflex.MergeManager = new RestrictColsMergeManager();

}

//上にあるセルもマージする場合
private void InitializeRestrictRows()
{
    for (int i = 0; i < 4; i++)
    {
        _restrictRowsflex.Columns.Add(new C1.WPF.FlexGrid.Column());
    }
    for (int i = 0; i < 2; i++)
    {
        _restrictRowsflex.Rows.Add(new C1.WPF.FlexGrid.Row());
    }
    _restrictRowsflex.AllowMerging = AllowMerging.All;
    _restrictRowsflex.MergeManager = new RestrictRowsMergeManager();
    _restrictRowsflex[0, 0] = "関東";
    _restrictRowsflex[0, 1] = "関東";
    _restrictRowsflex[0, 2] = "関西";
    _restrictRowsflex[0, 3] = "関西";
    _restrictRowsflex[1, 0] = "北海道";
    _restrictRowsflex[1, 1] = "北海道";
    _restrictRowsflex[1, 2] = "北海道";
    _restrictRowsflex[1, 3] = "北海道";
}

IMergeManager インターフェイスを実装するクラスは、次のように作成します。

コードのコピー
Class RestrictRowsMergeManager
    Implements C1.WPF.FlexGrid.IMergeManager

    Public Function GetMergedRange(grid As C1FlexGrid, cellType__1 As CellType, rg As CellRange) As CellRange Implements IMergeManager.GetMergedRange
        ' データセルの結合を対象します 
        ' (行または列ヘッダを結合しない場合)
        If cellType__1 = CellType.Cell Then
            Dim isMerged As Boolean = False
            If grid.Tag Is Nothing Then
                grid.Tag = New List(Of Boolean)()
            End If
            Dim list = TryCast(grid.Tag, List(Of Boolean))
            If rg.Row = 0 OrElse (rg.Row > 0 AndAlso list(rg.Row - 1)) Then
                ' 左右に拡張します
                For i As Integer = rg.Column To grid.Columns.Count - 2
                    If GetDataDisplay(grid, rg.Row, i) <> GetDataDisplay(grid, rg.Row, i + 1) Then
                        Exit For
                    End If
                    rg.Column2 = i + 1
                    isMerged = True
                Next
                For i As Integer = rg.Column To 1 Step -1
                    If GetDataDisplay(grid, rg.Row, i) <> GetDataDisplay(grid, rg.Row, i - 1) Then
                        Exit For
                    End If
                    rg.Column = i - 1
                    isMerged = True
                Next
            End If

            list.Add(isMerged)
        End If

        ' 完了
        Return rg
    End Function
    Private Function GetDataDisplay(grid As C1FlexGrid, r As Integer, c As Integer) As String
        Return grid(r, c).ToString()
    End Function
コードのコピー
class RestrictRowsMergeManager : IMergeManager
{
    public CellRange GetMergedRange(C1FlexGrid grid, CellType cellType, CellRange rg)
    {
        // データセルの結合を対象します 
        // (行または列ヘッダを結合しない場合)
        if (cellType == CellType.Cell)
        {
            bool isMerged = false;
            if (grid.Tag == null)
                grid.Tag = new List<bool>();
            var list = grid.Tag as List<bool>;
            if (rg.Row == 0 || (rg.Row > 0 && list[rg.Row - 1]))
            {
                // 左右に拡張します
                for (int i = rg.Column; i < grid.Columns.Count - 1; i++)
                {
                    if (GetDataDisplay(grid, rg.Row, i) != GetDataDisplay(grid, rg.Row, i + 1)) break;
                    rg.Column2 = i + 1;
                    isMerged = true;
                }
                for (int i = rg.Column; i > 0; i--)
                {
                    if (GetDataDisplay(grid, rg.Row, i) != GetDataDisplay(grid, rg.Row, i - 1)) break;
                    rg.Column = i - 1;
                    isMerged = true;
                }
            }
            
            list.Add(isMerged);
        }

        // 完了
        return rg;
    }
    string GetDataDisplay(C1FlexGrid grid, int r, int c)
    {
        return grid[r, c].ToString();
    }
}

注意:

  • 固定セルと通常セルはマージされません。
  • 行と列のマージが同時に行われた場合、列のマージが優先されます。
  • カスタムマージと自動マージを同時に実装することはできません。