如何使用DBLookupComboBox选择外键值而不立即更改目标表?(Delphi 5 Pro)
基本情景:如何使用DBLookupComboBox选择外键值而不立即更改目标表?(Delphi 5 Pro),delphi,combobox,foreign-keys,delphi-5,Delphi,Combobox,Foreign Keys,Delphi 5,基本情景: 用户单击“编辑项目” “编辑”对话框打开 组合框“项目类型”应填充表格“项目类型”中的项目。组合框应显示“item\u type.name”,但也应知道“item\u type.id” 用户编辑其他项目内容并选择项目类型,然后单击“确定” 我的程序做一些输入验证 如果一切正常,从所选组合项中获取“item_type.id”,并将其保存到item表的外键列(“item.fk_item_type”) 如果我正确理解这个组件,我应该将DataSource设置为指向目标表“item”,将Da
我开始怀疑也许我错过了一件基本的事情。所有这些DB*组件,它们是否自动从数据库加载值,但我必须自己调用Post()?这意味着它们不会自动更改数据库中的值?如果我理解正确,您希望使用DBLookupComboBox。必须为以下属性提供值
- 数据源-链接到您正在编辑的表,可能是“项”
- datafield—您正在编辑的表中字段的名称,可能是“item\u type”
- listsource-链接到填充组合框的表,可能是“项类型”
- 列表字段-要显示的“项目类型”字段的名称,可能是“名称”
- key field(关键字段)-“item_types”(项目类型)字段的名称,该字段将插入到项目记录中,可能是“item_types”
Function TEditQuestion.Execute (n: longint): boolean;
var
gen: longint;
begin
sdsEditQuestion.params[0].asinteger:= n; // TSQLDataSet
with qEditQuestion do // TClientDataSet
begin
open;
if n = -1 then // new record
begin
caption:= 'New record';
insert;
fieldbyname ('alive').asinteger:= 1;
// initialise necessary fields in the dataset
end
else caption:= 'Editing record ' + inttostr (n);
edit;
if showmodal = mrOK then
begin
// validation code comes here. Set 'result' to true if everything is ok
if result then
begin
if n = -1 then
begin
with qGenID do
begin
open;
gen:= fields[0].asinteger; // get new value from generator
close
end;
FieldByName ('id').asinteger:= gen;
end;
post;
applyupdates (0)
end
else cancel // showmodal = OK, result = false
else // showmodal cancelled
begin
cancel;
result:= false
end;
end // with qEditQuestion
end;
如果我理解正确,您希望使用DBLookupComboBox。必须为以下属性提供值
- 数据源-链接到您正在编辑的表,可能是“项”
- datafield—您正在编辑的表中字段的名称,可能是“item\u type”
- listsource-链接到填充组合框的表,可能是“项类型”
- 列表字段-要显示的“项目类型”字段的名称,可能是“名称”
- key field(关键字段)-“item_types”(项目类型)字段的名称,该字段将插入到项目记录中,可能是“item_types”
Function TEditQuestion.Execute (n: longint): boolean;
var
gen: longint;
begin
sdsEditQuestion.params[0].asinteger:= n; // TSQLDataSet
with qEditQuestion do // TClientDataSet
begin
open;
if n = -1 then // new record
begin
caption:= 'New record';
insert;
fieldbyname ('alive').asinteger:= 1;
// initialise necessary fields in the dataset
end
else caption:= 'Editing record ' + inttostr (n);
edit;
if showmodal = mrOK then
begin
// validation code comes here. Set 'result' to true if everything is ok
if result then
begin
if n = -1 then
begin
with qGenID do
begin
open;
gen:= fields[0].asinteger; // get new value from generator
close
end;
FieldByName ('id').asinteger:= gen;
end;
post;
applyupdates (0)
end
else cancel // showmodal = OK, result = false
else // showmodal cancelled
begin
cancel;
result:= false
end;
end // with qEditQuestion
end;
您可以将OnValidate-Event添加到
项中。fk\u项类型
字段claasic组合框可以填充项。AddObject(DisplayText,TObject(ID))。。。但是,您也可以使用TDBlookupComboBox而不分配数据源和数据字段,并使用属性KeyValue手动分配给item.fk_item_type。@bummi我看不到哪里可以“将事件添加到我的字段”。你是说数据库触发器吗?我在DBLookupComboBox的事件列表中没有看到名为“OnValidate”的事件。@bummi我不知道Items.AddObject,听起来很有趣。我已经尝试过不分配数据源/数据字段,但是编辑字段中没有显示任何内容(仅在下拉列表中)。让我们为项添加OnValidate-Event。fk_item_type
字段claasic组合框可以填充项。AddObject(DisplayText,TObject(ID))。。。但是,您也可以使用TDBlookupComboBox而不分配数据源和数据字段,并使用属性KeyValue手动分配给item.fk_item_type。@bummi我看不到哪里可以“将事件添加到我的字段”。你是说数据库触发器吗?我在DBLookupComboBox的事件列表中没有看到名为“OnValidate”的事件。@bummi我不知道Items.AddObject,听起来很有趣。我已经尝试过不分配DataSource/DataField,但是在编辑字段中没有显示任何内容(仅在下拉列表中)。让我们看看,我并不固定使用DBLookupComboBox,只要是最容易完成任务的。你是说当用户做出选择时,数据源表不会被更改吗?@Zalumon:只有在你发布更改后,表才会被更改。通常,在用户按下“编辑”对话框上的“确定”按钮后会发生这种情况。您可以在发布数据之前验证OKBtnClick事件中的数据。我将在我的答案中添加一些代码,使其更清晰。啊,太好了,这可能解决了我的“问题”。不需要代码,这正是我想做的。@Zalumon:如果我的答案解决了你的问题,你能把它标记为选中的答案吗?当然,我花了整整一天的时间才真正测试了这个问题。我不固定使用DBLookupComboBox,只要最容易完成我的任务就行。你是说当用户做出选择时,数据源表不会被更改吗?@Zalumon:只有在你发布更改后,表才会被更改。通常,在用户按下“编辑”对话框上的“确定”按钮后会发生这种情况。您可以在发布数据之前验证OKBtnClick事件中的数据。我会在我的答案中添加一些代码,让它更清楚。啊,那个