FlexGrid for WinForms
連結モードの操作
データ > 連結モード > 連結モードの操作

連結モードでの非連結列の追加

連結モードのグリッドは、データソースからデータを取得し、それをレコードおよび連結列として表示します。列を追加してデータソースに存在しないデータを表示するには、設計時またはコードから非連結列を追加する必要があります。

設計時の非連結列の追加

  1. デザインビューで、FlexGrid コントロールを選択し、スマートタグをクリックしてC1FlexGrid タスクメニューを開きます。
  2. グリッドコントロールとデータソースを連結します。FlexGrid とデータソースを連結する手順については、「連結モード」を参照してください。
  3. [デザイナ]オプションをクリックして、C1FlexGrid 列エディタを開きます。
  4. 右側のペインで、グリッドプレビューから既存の列を選択します。
  5. ツールバーで[列の挿入]オプションをクリックして、選択した列の前または後に列を追加します。
    非連結列の追加

コードからの非連結列の追加

FlexGrid は、グリッドに非連結列を追加するために、ColumnCollection クラスの Add、Insert、およびInsertRange メソッドを提供しています。Add メソッドは末尾に列を追加します。Insert メソッドを使用すると、新しい列を追加する位置を指定できます。同様に、InsertRange メソッドを使用して、指定した位置に複数の列を追加できます。

以下のコードを使用して、連結 WinForms FlexGrid に非連結列を追加します。

// 連結されていない列を追加します
Column col = _flex.Cols.Add();
col.Name = col.Caption = "Unbound";
_flex[1, "Unbound"] = 123;
' 連結されていない列を追加します
Dim col As Column = C1FlexGrid1.Cols.Add()
col.Name = "Unbound"
col.Caption = "Unbound"
C1FlexGrid1(1, "Unbound") = 123

非連結列の値の設定

連結グリッドの非連結列に値を定義するには、C1FlexGrid クラスの SetUnboundValue イベントと GetUnboundValue イベントを使用する必要があります。最初に、入力値を格納するためのハッシュテーブルを作成します。次に、SetUnboundValue イベントを使用し、レコードを識別する一意キーを使用してハッシュテーブルに非連結値を設定します。さらに、GetUnboundValue イベントを使用し、ハッシュテーブルに格納された値を一意キーで取得して、セルに表示する非連結値を設定します。

以下のコードは、連結 WinForms FlexGrid に追加された非連結列に値を設定する方法を示します。

// get value from hashtable using ProductID as key
void _flex_GetUnboundValue(object sender, C1.Win.C1FlexGrid.UnboundValueEventArgs e)
{
       DataRowView drv = (DataRowView)_flex.Rows[e.Row].DataSource;
   e.Value = _hash[drv["ProductID"]];
}

// store value in hashtable using ProductID as key
void _flex_SetUnboundValue(object sender, C1.Win.C1FlexGrid.UnboundValueEventArgs e)
{
       DataRowView drv = (DataRowView)_flex.Rows[e.Row].DataSource;
        _hash[drv["ProductID"]] = e.Value;
}
Private Sub C1FlexGrid1_GetUnboundValue(sender As Object, e As C1.Win.C1FlexGrid.UnboundValueEventArgs) Handles C1FlexGrid1.GetUnboundValue
    Dim drv As DataRowView = DirectCast(C1FlexGrid1.Rows(e.Row).DataSource, DataRowView)
    e.Value = _hash(drv("ProductID"))
End Sub

Private Sub C1FlexGrid1_SetUnboundValue(sender As Object, e As C1.Win.C1FlexGrid.UnboundValueEventArgs) Handles C1FlexGrid1.SetUnboundValue
    Dim drv As DataRowView = DirectCast(C1FlexGrid1.Rows(e.Row).DataSource, DataRowView)
    _hash(drv("ProductID")) = e.Value
End Sub

固定列のデータの表示

固定列に値を設定するには、フォームロードイベントで C1FlexGrid クラスの DrawMode プロパティに OwnerDraw を設定し、次に OwnerDrawCell イベントを作成して固定列セルに値を設定します。この例では、連結 WinForms FlexGrid の固定列に行番号を設定しています。

Displaying data in fixed column

   private void C1FlexGrid1_OwnerDrawCell(object sender, OwnerDrawCellEventArgs e)
        
   {
     if ((e.Row >= this.c1FlexGrid1.Rows.Fixed) & (e.Col == (this.c1FlexGrid1.Cols.Fixed - 1)))
      {
        e.Text = e.Row.ToString(); // または任意のテキスト   
      }
   }                     
Private Sub C1FlexGrid1_OwnerDrawCell(ByVal sender As Object, ByVal e As OwnerDrawCellEventArgs)
    If e.Row >= Me.c1FlexGrid1.Rows.Fixed And e.Col = Me.c1FlexGrid1.Cols.Fixed - 1 Then
        e.Text = e.Row.ToString() ' または任意のテキスト  
    End If
End Sub

列幅の自動調整

FlexGrid には、テキスト長に合わせて自動的に列幅を調整するために、C1FlexGrid クラスの AutoResize プロパティがあります。データソースに連結して適切な列幅でグリッドをロードするには、このプロパティに true を設定しておく必要があります。 AutoSizeCol メソッドを呼び出して、指定した列の幅を調整することもできます。

以下のコードを使用して、WinForms FlexGrid でテキストに合わせて列幅を自動調整します。

   // すべての列の幅を自動的に調整します                
   c1FlexGrid1.AutoResize = true;

   // 4列目の幅を自動調整します
   // c1FlexGrid1.AutoSizeColumns(3);     
  ' すべての列の幅を自動的に調整します                
  c1FlexGrid1.AutoResize = True

  ' 4列目の幅を自動調整します
  ' c1FlexGrid1.AutoSizeColumns(3)          

フィールドへのビットマップ画像の表示

大部分のシナリオでは、グリッドは、データソースから画像を直接取得します。ただし、Microsoft Access のように画像を OLE オブジェクトとして格納するデータベースにグリッドが連結されている場合は、ビットマップ画像を取得するために多少余分な処理が必要です。このような場合は、バイト配列として格納された画像データをメモリストリームに変換し、次に OwnerDrawCell イベントを使用して画像を読み込む必要があります。 フォームロードイベントで、DrawMode プロパティに OwnerDraw を設定する必要があります。また、画像を適切に表示するために行の高さを調整します。

以下のコードは、WinForms FlexGrid のフィールドにビットマップ画像を表示する方法を具体的に示しています。

    private void C1FlexGrid1_OwnerDrawCell(object sender, C1.Win.C1FlexGrid.OwnerDrawCellEventArgs e)
     {
       if(!e.Measuring && e.Row>=c1FlexGrid1.Rows.Fixed && e.Col >= c1FlexGrid1.Cols.Fixed)
        {
         // 「Photo」はblob(byte [])に保存された画像です
         if (c1FlexGrid1.Cols[e.Col].Name == "Picture")
              {
                // mdbからロードしてみてください
                e.Image = LoadImage(c1FlexGrid1[e.Row, e.Col] as byte[]);

               // 画像が表示された場合は、テキストを入力しないでください
                if (e.Image != null) e.Text = null;
                }
            }
        }                         
Private Sub C1FlexGrid1_OwnerDrawCell(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.OwnerDrawCellEventArgs)
    If Not e.Measuring AndAlso e.Row >= c1FlexGrid1.Rows.Fixed AndAlso e.Col >= c1FlexGrid1.Cols.Fixed Then

        ' 「Photo」はblob(byte [])に保存された画像です
        If c1FlexGrid1.Cols(e.Col).Name Is "Picture" Then
            ' mdbからロードしてみてください
            e.Image = LoadImage(TryCast(c1FlexGrid1(e.Row, e.Col), Byte()))

            ' 画像が表示された場合は、テキストを入力しないでください
            If e.Image IsNot Nothing Then e.Text = Nothing
        End If
    End If
End Sub     

上のサンプルコードでは、カスタムメソッドの LoadImage メソッドを使用して、画像をバイト配列からメモリストリームに変換しています。

Image LoadImage(byte[] picData)
   static Image LoadImage(byte[] picData)
   {
      // これが埋め込みオブジェクトであることを確認してください
        const int bmData = 78;
        if (picData == null || picData.Length < bmData + 2) return null;
        if (picData[0] != 0x15 || picData[1] != 0x1c) return null;

      // 現在点ではビットマップのみを処理します
         if (picData[bmData] != 'B' || picData[bmData + 1] != 'M') return null;

     // 画像をロードします
        Image img = null;
          try
            {
                MemoryStream ms = new MemoryStream(picData, bmData, picData.Length - bmData);
                img = Image.FromStream(ms);
            }
            catch { }

      // 画像を返します
         return img;
        }   
Private Function LoadImageMethod(ByVal picData As Byte()) As Image

 Private Shared Function LoadImage(ByVal picData As Byte()) As Image
   ' これが埋め込みオブジェクトであることを確認してください
   Const bmData As Integer = 78
   If picData Is Nothing OrElse picData.Length < bmData + 2 Then Return Nothing
   If picData(0) <> &H15 OrElse picData(1) <> &H1c Then Return Nothing

   ' 現在点ではビットマップのみを処理します
   If picData(bmData) <> "B"c OrElse picData(bmData + 1) <> "M"c Then Return Nothing

   ' 画像をロードします
   Dim img As Image = Nothing

   Try
     Dim ms As MemoryStream = New MemoryStream(picData, bmData, picData.Length - bmData)
     img = Image.FromStream(ms)
   Catch
   End Try

   ' 画像を返します
   Return img
End Function