FlexGrid for WPF
チェックボックスを表示する
基本操作 > セル > チェックボックスを表示する

グリッドを連結モードで使用している場合は、行や列のデータ型(DataType)がブール型であれば、自動的にチェックボックスが表示されます。しかし、非連結モードの場合は、グリッドはセルの値を直接セルに格納し、Object型のデータを文字列に変換しています。それで、ブール型のデータを Excel のように True/False として解釈して表示しています。

この場合、C1FlexGrid でカスタムセルファクトリを使用してコントロールのデフォルト動作をオーバーライドする方法が用意されています。
この強力な機能は、WinForms版の SetCellChecked メソッドを使用する方法に比べて少し複雑ですが、より柔軟な方法です。たとえば、ブール型データを自動的にチェックボックスとして表示するようなカスタムセルファクトリを作成するか、チャックボックスを直接セルに格納してカスタムセルファクトリがそのセル内のコントロールを簡単に表示するような方法は実現可能になります。

次のコードでは、下記のシナリオを実現するカスタムセルファクトリを使用してセルにチェックボックスを表示します:

  1. セルにブール型のデータがある場合、ファクトリがそのセルに対してチェックボックスを作成します
  2. セルにコントロールオブジェクトがある場合、ファクトリがそのセルにコントロールを表示します 

【実行例】

コードのコピー
Public Class MyCellFactory
    Inherits CellFactory
    Public Overrides Sub CreateCellContent(grid As C1FlexGrid, bdr As System.Windows.Controls.Border, rng As CellRange)
        If TypeOf grid.Cells(rng.Row, rng.Column) Is Boolean Then
            ' 値を表示/編集するために、チェックボックスを作成します
            Dim chk As New CheckBox()
            chk.IsChecked = DirectCast(grid.Cells(rng.Row, rng.Column), System.Nullable(Of Boolean))
            chk.VerticalAlignment = VerticalAlignment.Center
            chk.HorizontalAlignment = HorizontalAlignment.Center
            ToolTipService.SetToolTip(chk, "このチェックボックスはグリッドセルに格納するブール値を表します")
            ' チェックボックスをセル要素に割り当てます
            bdr.Child = chk
            ' グリッドセルの内容が更新されるように、チェックボックスを接続します
            chk.Tag = grid

            chk.[AddHandler](CheckBox.ClickEvent, New RoutedEventHandler(AddressOf chk_Click))
        ElseIf TypeOf grid.Cells(rng.Row, rng.Column) Is Control Then
            ' コントロールをセルに追加します(親がない場合)
            Dim ctl As Control = DirectCast(grid.Cells(rng.Row, rng.Column), Control)
            If ctl.Parent Is Nothing Then
                bdr.Child = DirectCast(grid.Cells(rng.Row, rng.Column), System.Windows.Controls.Control)

            End If
        Else
            ' ブール値ではない場合、デフォルト動作を実現
            MyBase.CreateCellContent(grid, bdr, rng)
        End If
    End Sub
    ' チェックボックスがクリックされた場合、値を更新します
    Private Sub chk_Click(sender As Object, e As EventArgs)
        ' クリックされたチェックボックスを取得します
        Dim chk As CheckBox = DirectCast(sender, CheckBox)
        ' チェックボックスを保持するグリッドを取得します
        Dim flex As C1FlexGrid = DirectCast(chk.Tag, C1FlexGrid)
        ' チェックボックスを持つセルを取得します
        Dim bdr As Border = DirectCast(chk.Parent, Border)
        'int row = bdr.GetValue(Grid.RowProperty.GlobalIndex);
        Dim row As Integer = CInt(bdr.GetValue(Grid.RowProperty))
        Dim col As Integer = CInt(bdr.GetValue(Grid.ColumnProperty))
        ' セルに新しい値を割り当てます
        flex(row, col) = chk.IsChecked
    End Sub
    ' セルが廃却された場合、セルの境界のコンテンツも削除します
    Public Overrides Sub DisposeCell(grid As C1.WPF.FlexGrid.C1FlexGrid, cellType As C1.WPF.FlexGrid.CellType, cell As System.Windows.FrameworkElement)
        Dim bdr As Border = DirectCast(cell, Border)
        bdr.Child = Nothing
    End Sub
End Class
コードのコピー
public class MyCellFactory : CellFactory
{
    public override void CreateCellContent(C1FlexGrid grid, System.Windows.Controls.Border bdr, CellRange rng)
    {

        if (grid.Cells[rng.Row, rng.Column] is bool)
        {
            
            // 値を表示/編集するために、チェックボックスを作成します
            CheckBox chk = new CheckBox();
            chk.IsChecked = (bool?)grid.Cells[rng.Row, rng.Column];
            chk.VerticalAlignment = VerticalAlignment.Center;
            chk.HorizontalAlignment = HorizontalAlignment.Center;
            ToolTipService.SetToolTip(chk, "このチェックボックスはグリッドセルに格納するブール値を表します");

            // チェックボックスをセル要素に割り当てます
            bdr.Child = chk;

            // グリッドセルの内容が更新されるように、チェックボックスを接続します
            chk.Tag = grid;
            chk.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(chk_Click));


        }
        else if (grid.Cells[rng.Row, rng.Column] is Control)
        {
            // コントロールをセルに追加します(親がない場合)
            Control ctl = (Control)grid.Cells[rng.Row, rng.Column];
            if (ctl.Parent == null)
            {
                  bdr.Child =(System.Windows.Controls.Control) grid.Cells[rng.Row, rng.Column];
            }


        }
        else
        {
            // ブール値ではない場合、デフォルト動作を実現
            base.CreateCellContent(grid, bdr, rng);

        }

    }

    // チェックボックスがクリックされた場合、値を更新します

    private void chk_Click(object sender, EventArgs e)
    {
        // クリックされたチェックボックスを取得します
        CheckBox chk = (CheckBox)sender;

        // チェックボックスを保持するグリッドを取得します
        C1FlexGrid flex = (C1FlexGrid)chk.Tag;

        // チェックボックスを持つセルを取得します
        Border bdr = (Border)chk.Parent;

        //int row = bdr.GetValue(Grid.RowProperty.GlobalIndex);
        int row =(int) bdr.GetValue(Grid.RowProperty);
        int col = (int)bdr.GetValue(Grid.ColumnProperty);

        //// セルに新しい値を割り当てます
        flex[row, col] = chk.IsChecked;

    }
    // セルが廃却された場合、セルの境界のコンテンツも削除します
    public override void DisposeCell(C1.WPF.FlexGrid.C1FlexGrid grid, C1.WPF.FlexGrid.CellType cellType, System.Windows.FrameworkElement cell)
    {
        Border bdr = (Border)cell;
        bdr.Child = null;
    }
}

次は、セルにコントロールを追加する方法を示します。

コードのコピー
' コントロールを追加します
Dim chk As New CheckBox()
ToolTipService.SetToolTip(chk, "このチェックボックスはグリッドセルに格納しています")
chk.VerticalAlignment = VerticalAlignment.Center
chk.HorizontalAlignment = HorizontalAlignment.Center
_fgUnbound(0, 1) = chk
Dim cmb As New ComboBox()
cmb.Items.Add("First")
cmb.Items.Add("Second")
cmb.Items.Add("Third")
ToolTipService.SetToolTip(chk, "このコンボボックスはグリッドセルに格納しています")
_fgUnbound(1, 1) = cmb
' カスタムセルファクトリに結びます
' (ブール値をチェックボックスとして表示する)
_fgUnbound.CellFactory = New MyCellFactory()
コードのコピー
// コントロールを追加します
CheckBox chk = new CheckBox();
ToolTipService.SetToolTip(chk, "このチェックボックスはグリッドセルに格納しています");
chk.VerticalAlignment = VerticalAlignment.Center;
chk.HorizontalAlignment = HorizontalAlignment.Center;
_fgUnbound[0, 1] = chk;

ComboBox cmb = new ComboBox();
cmb.Items.Add("First");
cmb.Items.Add("Second");
cmb.Items.Add("Third");
ToolTipService.SetToolTip(chk, "このコンボボックスはグリッドセルに格納しています");
_fgUnbound[1, 1] = cmb;

// カスタムセルファクトリに結びます
// (ブール値をチェックボックスとして表示する)
_fgUnbound.CellFactory = new MyCellFactory();