2013-03-21 138 views
1

我尝试构建一个从数据库读取数据并使用Firemonkey中的TGrid显示它的工具。我需要使用不同类型的列,如TCheckColumn和TPopupColumn,但找不到任何有关如何在C++ Builder中使用它们的好指南或示例。Firemonkey:在Embarcadero C++ Builder XE3上使用TGrid

任何方式,我设法了解TStringColumn,TProgressColumn的用法设置TGrid的事件onGetValue单元格的值。

是否有人知道如何设置TCheckColumn,TIm​​ageColumn和TPopupColumn类型的列的值?

感谢 丹尼尔

--- UPDATE ---

我设法使用TProgressColumn。这是我在窗体的构造做:

// 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); 
} 

当我点击一个复选框后,所有其他复选框会改变状态。所以组件工作正确......现在重点是如何以正确的方式将值设置为true或false。

回答

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; 

据我可以告诉一个弹出式菜单不能接受或提供的数据。

+0

实际上代码是非常类似的(我已经把我的代码放在帖子的更新中)。你有没有使用TCheckColumn? – 2013-03-22 14:57:58

+0

您是否在设置值时遇到问题,或者CheckColumn是否忽略了您设置的值? – 2013-03-22 17:53:44

+0

实际上,我发现如果将OnSetValue方法中的单元格的值保存并将其分配给OnGetValue方法中的单元格,则其他行会更改它的状态。 – 2013-03-27 10:03:59

1

TGris不存储任何数据,您应该创建自己的数据存储。

例子:TGrid与TCheckColumn,TStringColumn和TPopupColumn

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

0

后收到OnSetValue为了解决您的问题,重新定义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(); 
} 
} 
//---------------------------------------------------------------------------