« 管理者として起動したWindows VISTA / 7のアプリケーションにファイルをドロップしてみた | トップページ | Firebirdでテーブル一覧を得る »

2011-10-06

VCL TDrawGrid, TStringGridにComboBoxを使う

通常の、goEditingでは、TInplaceEditが使われますが、これをTInplaceEditListに代えてやればOK。

あとは、TCustomGridのGetEditStyle関数が、戻すTEditStyleによって、エディタの挙動が変わります。esSimpleが普通の状態、esPickListでコンボボックス、esEllipsisで参照ボタンのような点が3つ描かれたボタンが表示されます。

TEditStyle __fastcall GetEditStyle (int ACol, int ARow);

TInplaceEditListクラスには、OnGetPickListitems、OnEditButtonClickというイベントハンドラプロパティが用意されていて、OnGetPickListitemは、内部エディタがPickListの要素を要求した時に発生するので、ここで任意の要素を設定すれば、セルの座標に応じたリストを表示する事ができる。OnEditButtonClickはesEllipsisの時に表示されるボタンのクリックに対応する。普通に考えるとOpenDialogを表示して、ファイル名をセルに描画するという感じになると思う。

TInplaceEditをTInplaceEditListに変えるには、TCustomGrid::CreateEditor関数でTInplaceEdit*を返す。TInplaceEditListは、TInplaceEditの派生クラスなので、TInplaceEditListを生成して返してやれば良いのだが、上記2つのイベントハンドラの設定が必要になる。

TInplaceEdit * __fastcall CreateEditor ();

で、簡単にこれらをグリッドで管理してしまおうと思う。ついでに、GetEditStyleをフォームなどから操作できるように、コールバック化する。

typedef void __fastcall (__closure* TOnGetEditStyle) (int ACol, int ARow, TEditStyle& AStyle);

class TMyGrid : public TStringGrid
{
private:
TOnGetEditStyle FOnGetEditStyle;
TOnGetPickListItems FOnGetPickListItems;
TNotifyEvent FOnEditButtonClick;
protected:
DYNAMIC TEditStyle __fastcall GetEditStyle (int ACol, int ARow)
{
TEditStyle style = esSimple;

if (NULL != FOnGetEditStyle)
{
FOnGetEditStyle (ACol, ARow, style);
}

return style;
}

TInplaceEdit* __fastcall CreateEditor ()
{
TInplaceEditList* editor = new TInplaceEditList (this);

editor->OnGetPickListitems = FOnGetPickListItems;
editor->OnEditButtonClick = FOnEditButtonClick;

return editor;
}

virtual void __fastcall SetOnGetPickListItems (TOnGetPickListItems event)
{
FOnGetPickListItems = event;

TInplaceEditList* editor =
dynamic_cast <TInplaceEditList*> (InplaceEditor);

if (NULL != editor)
{
editor->OnGetPickListitems = FOnGetPickListItems;
}
}

virtual void __fastcall SetOnEditButtonClick (TNotifyEvent event)
{
FOnEditButtonClick = event;

TInplaceEditList* editor =
dynamic_cast <TInplaceEditList*> (InplaceEditor);

if (NULL != editor)
{
editor->OnEditButtonClick = FOnEditButtonClick;
}
}

public:
__fastcall TMyGrid (TComponent* Owner)
: TStringGrid (Owner),
FOnGetEditStyle (NULL),
FOnGetPickListItems (NULL),
FOnEditButtonClick (NULL)
{
}

virtual __fastcall ~TMyGrid ()
{
}

__published:
__property TOnGetEditStyle OnGetEditStyle =
{ read = FOnGetEditStyle, write = FOnGetEditStyle };

__property TOnGetPickListItems OnGetPickListItems =
{ read = FOnGetPickListItems, write = SetOnGetPickListItems };

__property TNotifyEvent OnEditButtonClick =
{ read = FOnEditButtonClick, write = SetOnEditButtonClick };
};

あとは、このグリッドをフォームのメンバにして、フォーム側でOnGetPickListItems、OnEditButtonClick, OnGetEditStyleを実装してから、グリッドのプロパティにセットしてやる。

OnEditButtonClickでオープンダイアログを表示するために、フォームにはOpenDialogを置いておく。

class TForm1 : public TForm
{
__published:
TOpenDialog* OpenDialog1;
private:
TStringList* FStringList1;
TStringList* FStringList2;
public:
TMyGrid* MyGrid;

__fastcall TForm1 (TComponent *Owner)
: TForm (Owner),
MyGrid (new TMyGrid (this)),
FStringList1 (new TStringList),
FStringList2 (new TStringList)
{
MyGrid->Parent = this;
MyGrid->Options += TGridOptions () << goEditing << goColSizing;
MyGrid->Align = alClient;
MyGrid->FixedRows = 1;
MyGrid->FixedCols = 1;
MyGrid->RowCount = 5;
MyGrid->ColCount = 5;

MyGrid->OnGetEditStyle = MyGridGetEditStyle;
MyGrid->OnGetPickListItems = MyGridGetPickListItems;
MyGrid->OnEditButtonClick = MyGridEditButtonClick;

FStringList1->Append (L”リスト1-1”);
FStringList1->Append (L”リスト1-2”);
FStringList1->Append (L”リスト1-3”);

FStringList2->Append (L”リスト2-1”);
FStringList2->Append (L”リスト2-2”);
FStringList2->Append (L”リスト2-3”);
}

virtual __fastcall ~TForm1 ()
{
delete MyGrid;
delete FStringList1;
delete FStringList2;
}

void __fastcall MyGridGetEditStyle (int ACol, int ARow, TEditStyle& AStyle)
{
switch (ACol)
{
case 1:
case 2:
AStyle = esPickList;
break;

case 3:
AStyle = esEllipsis;
break;

default:
AStyle = esSimple;
}
}

void __fastcall MyGridGetPickListItems (int ACol, int ARow, TStrings* Items)
{
switch (ACol)
{
case 1:
Items->Assign (FStringList1);
break;

case 2:
Items->Assign (FStringList2);
break;
}
}

void __fastcall MyGridEditButtonClick (TObject *Sender)
{
if (OpenDialog1->Execute ())
{
MyGrid->Cells [MyGrid->Col][MyGrid->Row] =
OpenDialog1->FileName;
}
}
};

image

image

image

コンポーネントにしておけば、普段から簡単に使えるんじゃないかと思う。コンパイルには#include <Grids.hpp>が必要

|

« 管理者として起動したWindows VISTA / 7のアプリケーションにファイルをドロップしてみた | トップページ | Firebirdでテーブル一覧を得る »

CBuilder」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: VCL TDrawGrid, TStringGridにComboBoxを使う:

« 管理者として起動したWindows VISTA / 7のアプリケーションにファイルをドロップしてみた | トップページ | Firebirdでテーブル一覧を得る »