我正在尝试构建一个从数据库中读取数据的工具,并使用Firemonkey中的TGrid将其显示为表格。我需要使用不同类型的列,如TCheckColumn和TPopupColumn,但找不到任何关于如何在C ++ Builder中使用它们的好指南或示例。
无论如何,我设法理解TStringColumn的使用,TProgressColumn在TGrid的事件onGetValue中设置单元格的值。
您是否有人知道如何为TCheckColumn,TImageColumn和TPopupColumn类型的列设置值?
感谢 丹尼尔
--- --- UPDATE
我设法使用了TProgressColumn。这就是我在Form的构造函数中所做的:
// TStringColumn
Grid1->AddObject(new TStringColumn(this));
// TCheckColumn
TCheckColumn* c = new TCheckColumn(this);
Grid1->AddObject(c);
// TPopupColumn
// list of values
TStringList * l = new TStringList(NULL);
l->Add(L"First");
l->Add(L"Second");
l->Add(L"Third");
TPopupColumn* p = new TPopupColumn(this);
// adding the list to the PopupColumn
p->Items = l;
Grid1->AddObject(p);
// TProgressColumn
Grid1->AddObject(new TProgressColumn (this));
Grid1->RowCount = 3 ;
这是Grid1GetValue方法:
// TStringColumn
if(Col == 0) Value = TValue::From<String>(Row);
// TCheckColumn !! Can't make it work
if(Col == 1) Value = TValue::From<Boolean>(true);
// TPopupColumn
if(Col == 2) Value = TValue::From<int>(2);
// TProgressColumn
if(Col == 3) Value = TValue::From<double>(50.0);
--- --- UPDATE
如果我使用方法OnSetValue
保存列的值void __fastcall TForm1::Grid1SetValue(...)
{
if(Col == 1) check = Value;
}
然后使用OnGetValue方法设置它:
void __fastcall TForm1::Grid1GetValue(...)
{
// TCheckColumn !! Can't make it work
if(Col == 1) Value = check;// TValue::From<Boolean>(true);
}
点击一个复选框后,所有其他复选框都会改变状态。所以组件正常工作......现在重点是如何以正确的方式将Value设置为true或false。
答案 0 :(得分:1)
TGris不存储任何数据,您应该创建自己的数据存储。
示例:带有TCheckColumn,TStringColumn和TPopupColumn的TGrid
type
TField = record
Checked: Boolean;
Name: string;
Column: Byte;
end;
var
Fields: TList<TField>;
function SetField(const AChecked: Boolean; const AName: string; const AColumn: Byte): TField;
begin
with Result do begin
Checked := AChecked;
Name := AName;
Column := AColumn;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
Fields := TList<TField>.Create;
Fields.Add(SetField(True, 'Name', 1));
Fields.Add(SetField(True, 'Login', 2));
Fields.Add(SetField(True, 'Password', 3));
for I := 1 to Fields.Count do
PopupColumn1.Items.Add('Column ' + IntToStr(I));
gdFields.RowCount := Fields.Count;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Fields.Free;
end;
procedure TFormExport.gdFieldsGetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue);
begin
case gdFields.Columns[Col].TabOrder of
0: Value := Fields[Row].Checked;
1: Value := Fields[Row].Name;
2: Value := Fields[Row].Column - 1;
end;
end;
procedure TFormExport.gdFieldsSetValue(Sender: TObject; const Col, Row: Integer; const Value: TValue);
var
FRec: TField;
begin
FRec := Fields[Row];
case gdFields.Columns[Col].TabOrder of
0: FRec.Checked := Value.AsBoolean;
1: FRec.Name := Value.AsString;
2: FRec.Column := Value.AsInteger + 1;
end;
Fields[Row] := FRec;
end;
现在编辑TGrid后,数据存储中的所有数据都会被更改,但TGrid中可能存在错误 - 更改PopupColumn后从未收到过OnSetValue
答案 1 :(得分:0)
我无法提供C ++代码,但Delphi示例应该很容易翻译。
通过侦听OnGetData和OnSetData事件,获取并设置所有单元格值,获取类型TValue(XE3及更高版本)的take / give值。这只是在TValue中返回相应类型的情况:
uses System.RTTI;
procedure Form1.Grid1GetValue(Sender: TObject;const Col, Row: Integer;var Value: TValue);
begin
if Col = 1 then
Value := TValue.From<Integer>(1)
else if Col = 2 then
Value := TValue.From<String>('Hello')
else if Col = 3 then
Value := Tvalue.From<Single>(1.0);
end;
procedure Form1.Grid1SetValue(Sender: TObject;const Col, Row: Integer;const Value: TValue);
begin
if Col = 1 then
I := Value.As<Integer>
else if Col = 2 then
St := Value.As<String>
else if Col = 3 then
Si := Value.As<Single>;
end;
据我所知,弹出菜单无法接受或提供数据。
答案 2 :(得分:0)
为了解决您的问题,请按以下方式重新定义TCheckCell
课程:
#include <FMX.Grid.hpp>
#include <boost/dynamic_bitset.hpp>
class CheckCellClass:public TCheckCell
{
public:
__fastcall virtual CheckCellClass(System::Classes::TComponent*AOwner):TCheckCell(AOwner)
{
};
virtual System::Rtti::TValue __fastcall GetData(void)
{
return TValue::From<bool>(this->IsChecked);
};
virtual void __fastcall SetData(const TValue&Value)
{
TValue V(Value);
this->IsChecked=V.AsBoolean();
};
};
//Redifine TCheckColumn class
class CheckColumnClass:public TCheckColumn
{
private:
virtual Fmx::Controls::TStyledControl*__fastcall CreateCellControl(void)
{
CheckCellClass*Cell=new CheckCellClass(this);
Cell->OnChange =&(this->DoCheckChanged);
return Cell;
};
public:
__fastcall CheckColumnClass(System::Classes::TComponent*AOwner):TCheckColumn(AOwner)
{
};
};
//global Data for Save curent State Cell
boost::dynamic_bitset<unsigned char>FullDiscreteInputs;
Add To Grid In Constuctor
FullDiscreteInputs.resize(100);
DiscreteInputsGrid->RowCount=FullDiscreteInputs.size();
CheckColumnClass* DiscreteInPutsCheckColumn =new CheckColumnClass(DiscreteInputsGrid);
DiscreteInputsGrid->AddObject(CoilsCheckColumn);
void __fastcall TForm1::DiscreteInputsGridGetValue(TObject*Sender, const int Col, const int Row,TValue&Value)
{
//...
if(DiscreteInputsGrid->ColumnByIndex(Col)==DiscreteInPutsCheckColumn)
{
Value=TValue::From<bool>(FullDiscreteInputs[Row]);
}
//...
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DiscreteInputsGridSetValue(TObject*Sender, const int Col, const int Row, const TValue&Value)
{
TValue V(Value);
if(DiscreteInputsGrid->ColumnByIndex(Col)==DiscreteInPutsCheckColumn)
{
FullDiscreteInputs[Row]=V.AsBoolean();
}
}
//---------------------------------------------------------------------------