我有一些链接到AdoQuery的TEdits和一个链接到StringGrid的TEdits。因此,当我更改网格中的选择时,编辑也会更改其内容,并从所选单元格中获取数据。这是自动的,没有任何代码行。
但是当我使用#include <stdlib.h>
#include <stdio.h>
struct FooBar {
int bar;
} FooBar;
struct FooBar *foo(void)
{
struct FooBar *test = malloc(sizeof(*test));
test->bar = 42;
return test;
}
int main (void)
{
printf("%d\n", foo()->bar);
return 1;
}
属性过滤AdoQuery时,这个自动操作不起作用,并且Edits只获取第一个单元格值。
如何过滤AdoQuery并保持此StringGrid-Edits链接正常工作?
编辑:我已经添加了问题的图像,如您所见,即使选择了第二个记录,编辑仍保留第一个记录的值。忽略其他列,只有两个正在测试中。
答案 0 :(得分:2)
看看下面的示例代码,这是一个自包含的示例 ClientDataSet通过LiveBindings连接到一些TEdits和一个TStringGrid,用 在命名的TField中对值赋予过滤器的工具。我也包括在内 DFM的相关部分,以便您可以看到实时绑定。
该项目包括一个连接到DataSource1的标准TDBGrid,用于比较它 使用TStringGrid的行为。
不考虑过滤问题,只需编译并运行项目。使用Delphi 西雅图,我在StringGrid中看到的不是ID = 5的行,而是两行 ID = 6,这显然是错误的。 DBGrid正确显示行,包括 ID = 5。
使用DBNavigator,edID,edName和edValue在StringGrid中移动 即使StringGrid没有,TEDits也会显示正确的值。如果我 使用edName TEdit开始编辑ID = 6的第一行的Name列 StringGrid立即纠正自己以显示行ID = 5而不是第一个ID = 6。
因此,在这个简单的项目中,实时绑定似乎有问题,即使没有进行过滤也是如此。我发现如果ClientDataSet的IndexFieldNames属性设置为&#39; ID; Name&#39;。
,我所描述的问题就不会发生。然而,尽管有上述怪癖,请使用edFilterFieldName和 edFilterValue TEdits似乎工作正常,似乎没有显示问题 你说你有。我已经使用了ClientDataSet,因此我可以生成 项目代码中的一些测试数据。但是,我无法立即明白为什么 以类似的方式过滤AdoQuery会有问题。
代码
TForm1 = class(TForm)
StringGrid1: TStringGrid;
DataSource1: TDataSource;
edFilterFieldName: TEdit;
edFilterValue: TEdit;
Memo1: TMemo;
CDS1: TClientDataSet;
CDS1Name: TStringField;
CDS1Value: TStringField;
edName: TEdit;
edValue: TEdit;
BindingsList1: TBindingsList;
CDS1ID: TIntegerField;
DBGrid1: TDBGrid;
edID: TEdit;
LinkControlToField1: TLinkControlToField;
BindSourceDB1: TBindSourceDB;
LinkControlToField2: TLinkControlToField;
LinkControlToField3: TLinkControlToField;
LinkGridToDataSource1: TLinkGridToDataSource;
DBNavigator1: TDBNavigator;
procedure FormCreate(Sender: TObject);
procedure edFilterFieldNameChange(Sender: TObject);
procedure edFilterValueChange(Sender: TObject);
procedure CDS1NewRecord(DataSet: TDataSet);
private
FFilterFieldName : String;
FFilterValue : String;
procedure SetFilterFieldName(const Value: String);
procedure SetFilterValue(const Value: String);
procedure UpdateFilter;
public
NextID : Integer;
property FilterFieldName : String read FFilterFieldName write SetFilterFieldName;
property FilterValue : String read FFilterValue write SetFilterValue;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
begin
// AutoPost := True;
CDS1.IndexFieldNames := 'ID';
CDS1.CreateDataSet;
for i := 1 to 6 do begin
CDS1.Insert;
CDS1.FieldByName('Name').AsString := 'Name ' + IntToStr(i);;
CDs1.FieldByName('Value').AsString := 'Value ' + IntToStr(i);
CDS1.Post;
end;
CDS1.First;
StringGrid1.Invalidate;
FilterFieldName := edFilterFieldName.Text;
FilterValue := edFilterValue.Text;
end;
procedure TForm1.CDS1NewRecord(DataSet: TDataSet);
begin
Inc(NextID);
DataSet.FieldByName('ID').AsInteger := NextID;
end;
procedure TForm1.edFilterFieldNameChange(Sender: TObject);
begin
FilterFieldName := edFilterFieldName.Text;
end;
procedure TForm1.edFilterValueChange(Sender: TObject);
begin
FilterValue := edFilterValue.Text;
end;
procedure TForm1.SetFilterFieldName(const Value: String);
begin
if FilterFieldName <> Value then begin
FFilterFieldName := Value;
UpdateFilter;
end;
end;
procedure TForm1.UpdateFilter;
var
Expr : String;
begin
if CDS1.FieldByName(FilterFieldName) = Nil then begin
CDS1.Filtered := False;
exit;
end;
CDS1.DisableControls;
if FilterValue <> '' then begin
Expr := FilterFieldName + ' like ' + QuotedStr('%' + FilterValue + '%');
// Expr := 'substring(FilterFieldName, 1, 1)' + ' = ' + QuotedStr(FilterValue);
Memo1.Lines.Add(Expr);
CDS1.Filter := Expr;
CDS1.Filtered := True;
end
else
CDS1.Filtered := False;
CDS1.EnableControls;
end;
procedure TForm1.SetFilterValue(const Value: String);
begin
if FilterValue <> Value then begin
FFilterValue := Value;
UpdateFilter;
end;
end;
部分DFM
object DBNavigator1: TDBNavigator
Left = 600
Top = 208
Width = 240
Height = 25
DataSource = DataSource1
TabOrder = 8
end
object DataSource1: TDataSource
DataSet = CDS1
Left = 128
Top = 24
end
object CDS1: TClientDataSet
Aggregates = <>
Params = <>
OnNewRecord = CDS1NewRecord
Left = 72
Top = 24
object CDS1ID: TIntegerField
FieldName = 'ID'
end
object CDS1Name: TStringField
FieldName = 'Name'
Size = 40
end
object CDS1Value: TStringField
FieldName = 'Value'
Size = 80
end
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 128
Top = 88
object LinkControlToField1: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceDB1
FieldName = 'ID'
Control = edID
Track = False
end
object LinkControlToField2: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceDB1
FieldName = 'Name'
Control = edName
Track = False
end
object LinkControlToField3: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceDB1
FieldName = 'Value'
Control = edValue
Track = False
end
object LinkGridToDataSource1: TLinkGridToDataSource
Category = 'Quick Bindings'
DataSource = BindSourceDB1
GridControl = StringGrid1
Columns = <
item
MemberName = 'ID'
end
item
MemberName = 'Name'
end
item
MemberName = 'Value'
end>
end
end
object BindSourceDB1: TBindSourceDB
DataSource = DataSource1
ScopeMappings = <>
Left = 216
Top = 32
end