FlexGrid for WinForms
行詳細
> 行詳細

行詳細は、行(レコード)に関連する追加情報を別の展開可能なレイヤの形で提供する機能です。 この場合、最初のレイヤである行には基本情報が含まれ、2 番目のレイヤには詳細な情報が含まれます。この機能は、追加情報が多過ぎて使用可能な画面内に表示できない場合や、レコードごとの追加情報に一貫性がない場合に特に便利です。

行詳細

FlexGrid は、IC1FlexGridRowDetail インタフェースを使用して行詳細機能を提供します。詳細行に置かれる詳細コントロールは、このインタフェースを実装します。また、FlexGrid は、InputPanel および FlexGrid というテンプレートユーザーコントロールを独立したアセンブリ C1.Win.C1FlexGrid.RowDetails.4.5.2.dll で提供しており、これらのコントロールを詳細行ですぐに使用できます。FlexGrid の任意の行に詳細セクションを追加でき、データを 1 つのテンプレートにグループ化してオプションで表示することができます。これにより、ユーザーは、行を選択するだけで、その行に関連する追加データを表示できます。また、グリッドには、組み込みの展開/折りたたみボタンも用意されており、展開可能な行内のデータの表示/非表示を制御できます。

行詳細機能がよく使用されるシナリオには、次のようなものがあります。

  1. フォーム内編集:InputPanel コントロールを置くことで、ユーザー入力を取得し、レコードに情報を挿入できるようにします。
  2. 階層グリッド:マスターグリッドと、レコードに関する追加情報を表示する詳細グリッドから成ります。
  3. カスタム行詳細:任意のコントロールを使用して行詳細テンプレートを作成できます。

これらのシナリオの実装方法について、以下のセクションで説明します。

フォーム内編集

FlexGrid は、詳細行に InputPanel コントロールを置くことで、フォーム内編集をサポートします。InputPanel コントロールには、フォームと同様に、ユーザーが値を入力したり編集することができるデータフィールドが含まれます。ユーザーがフィールドの編集を終了すると、値が選択した行に反映されます。 

フォーム内編集

FlexGrid でフォーム内編集を実装するには、C1.Win.C1FlexGrid.RowDetails.4.5.2.dll への参照を追加し、IC1FlexGridRowDetail インタフェースを実装済みの C1InputPanelRowDetail クラスを使用します。次に、このクラスのインスタンスを C1FlexGrid クラスの RowDetailProvider プロパティに割り当てます。これにより、InputPanel コントロールが詳細行に追加され、フォーム内編集が可能になります。

flexGrid.RowDetailProvider = (g, r) => new C1InputPanelRowDetail();
flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected;        
flexGrid.RowDetailProvider = Function(g, r) New C1InputPanelRowDetail()
flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected

階層ビュー

階層ビューは、マスター/詳細モデルのことです。最上位レベルのグリッドを「マスターグリッド」、グリッド内グリッドを「詳細グリッド」と言います。詳細グリッドには、マスターグリッドで展開された行に関する追加情報が表示されます。たとえば、次の例で示されているマスター/詳細構造では、Customer テーブルと Order テーブルが使用されています。これらのテーブルはどちらも、関係を定義する共通のデータ要素として CustomerID を持っています。

階層ビュー

FlexGrid で階層グリッドを実装するには、C1.Win.C1FlexGrid.RowDetails.4.5.2.dll への参照を追加し、IC1FlexGridRowDetail インタフェースを実装済みの C1FlexGridRowDetail クラスを使用します。次に、このクラスのインスタンスを C1FlexGrid クラスの RowDetailProvider プロパティに割り当てて、詳細行に別のグリッドをネストします。これで、階層グリッドインタフェースを作成できます。

 private void FlexGrid_Load(object sender, EventArgs e)
        {
            string conn = Util.GetConnectionString();
            var ds = new DataSet();
            string[] tables = "Customers, Orders".Split(',');
            foreach (string tableName in tables)
            {
                Util.FillTable(ds, tableName, conn);
            }
          
         // マスターグリッドと詳細グリッド間の関係を定義します
            ds.Relations.Add("Customers_Orders",
                ds.Tables["Customers"].Columns["CustomerID"],
                ds.Tables["Orders"].Columns["CustomerID"]);
            flexGrid.DataSource = ds;
            flexGrid.DataMember = "Customers";
            flexGrid.RowDetailProvider = (g, r) => new C1FlexGridRowDetail();
            flexGrid.AreRowDetailsFrozen = false;
        }
    }       
Private Sub FlexGrid_Load(ByVal sender As Object, ByVal e As EventArgs)
      Dim conn As String = Util.GetConnectionString()
      Dim ds = New DataSet()
      Dim tables As String() = "Customers, Orders".Split(","c)

      For Each tableName As String In tables
          Util.FillTable(ds, tableName, conn)
      Next
      ' マスターグリッドと詳細グリッド間の関係を定義します
      ds.Relations.Add("Customers_Orders", ds.Tables("Customers").Columns("CustomerID"), ds.Tables("Orders").Columns("CustomerID"))
      flexGrid.DataSource = ds
      flexGrid.DataMember = "Customers"
      flexGrid.RowDetailProvider = Function(g, r) New C1FlexGridRowDetail()
      flexGrid.AreRowDetailsFrozen = False
 End Sub

カスタム行詳細

グリッドの詳細行には、InputPanel コントロールと FlexGrid コントロールのほかに、カスタムコントロールを置くこともできます。たとえば、次の例では、テキストラベルコントロールが行にアタッチされ、グリッドのサイズに影響を与えることなく追加情報を得ています。

カスタム行詳細

FlexGrid でカスタム行詳細を実装するには、IC1FlexGridRowDetail インタフェースを実装するユーザーコントロールを作成する必要があります。たとえば、次のコードでは、詳細行に置かれるテキストラベルコントロールを表す CustomRowDetail というクラスを作成しています。次に、このクラスのオブジェクトを C1FlexGrid クラスの RowDetailProvider プロパティに割り当てて、カスタムコントロールが詳細行に追加情報を表示できるようにしています。

  private void CustomSample_Load(object sender, EventArgs e)
  {
     flexGrid.DataSource = DemoDataSource("Employees");
     flexGrid.RowDetailProvider = (g, r) => new CustomRowDetail();
     flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected;
     flexGrid.Cols["Notes"].Visible = false;
  }

   // 従業員に関するメモ付きのラベルを表示するカスタム行詳細クラス
   public class CustomRowDetail : C1Label, IC1FlexGridRowDetail
    {
        
      // FlexGrid詳細コントロールを表示する前にコントロールを設定するために使用されます
      void IC1FlexGridRowDetail.Setup(C1FlexGrid parentGrid, int rowIndex)
        {
            var bs = new BindingSource(parentGrid.DataSource, parentGrid.DataMember);
            bs.Position = parentGrid.Rows[rowIndex].DataIndex;
            DataField = "Notes";
            DataSource = bs;
        }
        
      // FlexGrid詳細コントロールのサイズを更新するために使用されます
      void IC1FlexGridRowDetail.UpdateSize(C1FlexGrid parentGrid, int rowIndex, Size proposedSize)
        {
            var srSz = parentGrid.ScrollableRectangle.Size;
            var sz = TextRenderer.MeasureText(Text, Font, srSz, TextFormatFlags.WordBreak);
            sz.Width = Math.Max(sz.Width, srSz.Width);
            Size = sz;
        }   
     }                                  
    Private Sub CustomSample_Load(ByVal sender As Object, ByVal e As EventArgs)
        flexGrid.DataSource = DemoDataSource("Employees")
        flexGrid.RowDetailProvider = Function(g, r) New CustomRowDetail()
        flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected
        flexGrid.Cols("Notes").Visible = False
    End Sub


    ' 従業員に関するメモ付きのラベルを表示するカスタム行詳細クラス
    Public Class CustomRowDetail
        Inherits C1Label
        Implements IC1FlexGridRowDetail


        ' FlexGrid詳細コントロールを表示する前にコントロールを設定するために使用されます
        Private Sub Setup(ByVal parentGrid As C1FlexGrid, ByVal rowIndex As Integer)
            Dim bs = New BindingSource(parentGrid.DataSource, parentGrid.DataMember)
            bs.Position = parentGrid.Rows(rowIndex).DataIndex
            DataField = "Notes"
            DataSource = bs
        End Sub


        ' FlexGrid詳細コントロールのサイズを更新するために使用されます
        Private Sub UpdateSize(ByVal parentGrid As C1FlexGrid, ByVal rowIndex As Integer, ByVal proposedSize As Size)
            Dim srSz = parentGrid.ScrollableRectangle.Size
            Dim sz = TextRenderer.MeasureText(Text, Font, srSz, TextFormatFlags.WordBreak)
            sz.Width = Math.Max(sz.Width, srSz.Width)
            Size = sz
        End Sub
    End Class