我有一些TEdits链接到AdoQuery,而另一个TEdits链接到StringGrid。因此,当我更改网格中的选择时,“编辑”也会更改其内容,并从选定的单元格中获取数据。这是自动的,没有任何代码行。但是,当我使用AdoQuery.Filtered
属性过滤AdoQuery时,此自动操作不起作用,并且Edits仅获得第一个单元格值。如何过滤AdoQuery并保持此StringGrid-Edits链接正常工作?
编辑:我已经添加了问题的图像,如您所见,即使选择了第二条记录,编辑仍保留第一条记录的值。忽略其他列,只有两个在测试中。
最佳答案
请看下面的示例代码,它是一个独立的示例
ClientDataSet通过LiveBindings连接到某些TEdit和TStringGrid,其中
一种对命名TField中的值强加过滤器的工具。我也包括了
DFM的相关部分,以便您可以看到实时绑定。
该项目包括连接到DataSource1的标准TDBGrid,以比较其
TStringGrid的行为。
抛开过滤问题,仅编译并运行项目。使用Delphi
西雅图,我在StringGrid中看到的是ID = 5的行,而没有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属性设置为“ ID; Name”,则不会发生上述问题。
但是,尽管有上述怪癖,仍使用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