【问题标题】:Reassigning a datasource at run-time在运行时重新分配数据源
【发布时间】:2013-03-13 21:46:41
【问题描述】:

我进行了一些搜索,但发现更多未回答的问题。 :)

使用 D5pro。

我想在运行时将 DataSource 重新分配给 TDBGrid。我有七个相同的结构化数据集,根据按钮单击,我希望在网格中显示适当的数据集。

我已经尝试了所有方法,但无法让它显示下一个 DataSet。它坚持在启动时分配的第一个。我开始过度使用方法,但仍然没有任何效果。这就是我现在的位置。

procedure SetSource(var aSrc : TDataSource);
begin
  aSrc.DataSet.Close;
  dbgridShowData.DataSource:=aSrc;
  aSrc.DataSet.Open;
  aSrc.DataSet.First;
  aSrc.DataSet.Refresh;
end;

我哪里错了?

谢谢

【问题讨论】:

  • 数据源绑定到他们的数据集是否正确?一个简单的 dbgrid.DataSource := Datasourcexy;应该够了。

标签: delphi tdbgrid


【解决方案1】:

您可以在运行时非常轻松地更改 DBGrid 显示的数据集。有两种方法:

1:使用分配给 DBGrid.DataSource 的单个 DataSource 并将 DataSource.DataSet 更改为所需的 DataSet。这是一个简单的例子,所有的赋值都是在运行时完成的。

procedure TForm1.FormCreate(Sender: TObject);
begin
  DBGrid1.DataSource := DataSource1;

  DataSet1.Active := true;
  DataSet2.Active := true;
  DataSet3.Active := true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  DataSource1.DataSet := DataSet1;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  DataSource1.DataSet := DataSet2;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  DataSource1.DataSet := DataSet3;
end;

2:为每个 DataSet 使用一个 DataSource,并将 DBGrid.DataSource 更改为所需的 DataSource。这是一个简单的例子,所有的赋值都是在运行时完成的。

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataSource1.DataSet := DataSet1;
  DataSource2.DataSet := DataSet2;
  DataSource3.DataSet := DataSet3;

  DataSet1.Active := true;
  DataSet2.Active := true;
  DataSet3.Active := true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  DBGrid1.DataSource := DataSource1;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  DBGrid1.DataSource := DataSource2;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  DBGrid1.DataSource := DataSource3;
end;

如果您定义 DBGrid 的列,则数据集的结构需要相同,否则您必须在更改显示的数据集时更改列定义。

我更喜欢为每个 DataSet 使用一个 DataSource,因为它更灵活。

【讨论】:

    【解决方案2】:

    您可能需要改为更改DataSource.DataSet

    procedure SetDataFromDataSet(const aDataSource: TDataSource;
      const aNewDataSet: TDataSet);
    begin
      aDataSource.DataSet.Close;
      aDataSource.DataSet := aNewDataSet;
      if not aNewDataSet.Active then
        aNewDataSet.Open;
    end;
    

    使用示例:

    SetDataFromDataSet(DataSource1, CustomerQuery); 
    

    不过,您可能不想像这样在全局范围内关闭和打开数据集。从调用代码中执行此操作可能会更好。当然,这取决于您的应用需要什么。

    【讨论】:

    • 我认为这将 1. 涵盖潜在问题(可疑数据源未正确绑定) 2. 如果考虑更改主/详细结构,那么数据源的数据集将是致命的。
    • 我认为您的第 2 点不适用(因为这与所提出的问题无关)。第1点可能对也可能不对;大多数应用程序使用附加到数据感知控件的单个数据源(例如TDBGrid)。在这种情况下,您可以将DataSource 附加到控件并更改DataSet;我有一个用于 dBASE 文件的通用查看器(使用 Advantage 数据库服务器),它允许您打开和浏览任何 .dbf 文件,它所做的只是将TableName 分配给TAdsTable,然后打开表;网格会自动创建必要的列并显示它。
    • 谢谢肯,但这只是清除了所有选择的所有内容。这里发生了一些奇怪的事情。全球开盘和收盘是最后的防线。随着挫败感的上升,我提前几个小时删除了我的 OpenDB 和 CloseDB 函数。没有主/细节问题,这些只是平面数据库。
    • 那你做错了。做一个新的应用程序(文件->新建->VCL表单应用程序)。将 TDBGrid、TDataSource 和 TADOTable 拖放到窗体上。将 DBGrid1.DataSource 设置为DataSource1,将DataSource1.DataSet 设置为ADOQuery1。为您选择的 ADO 数据库创建一个连接字符串,并快速编写一个 SELECT TOP 10 * FROM 您拥有的任何表。将ADOQuery1.Active 设置为true。网格应该显示数据。在另一个表上添加另一个ADOQuery、一个连接字符串和一个SELECT。将DataSource1.DataSet 更改为ADOQuery2,并将ADOQuery2.Active 设置为True
    • 现在将DataSource1.DataSet 设置回ADOQuery1。在表单上放置一个按钮并双击它。在代码编辑器中:if (DataSource1.DataSet = ADOQuery1) then DataSource1.DataSet := ADOQuery2 else DataSource1.DataSet := ADOQuery2;。运行您的应用程序,然后单击按钮。网格中的数据应该在两个ADOQuery 数据集之间来回变化。
    【解决方案3】:

    用 Delphi5 pro 测试。

    procedure TForm1.setDataSourceDataSet(var newDataSource:TDataSource);
    begin
    if DBgrid1.DataSource = nil then begin
       DBgrid1.DataSource:=newDataSource;
    end else begin
    if DBgrid1.DataSource.Name = newDataSource.Name then exit;
    DBGrid1.DataSource.Enabled:=False;
    DBgrid1.DataSource:=newDataSource;
    end;
    If DBgrid1.DataSource.DataSet.active=False then DBgrid1.DataSource.DataSet.active:=True;
    DBGrid1.DataSource.Enabled:=True;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    setDataSourceDataSet(DataSource1);
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    setDataSourceDataSet(DataSource2);
    end;
    

    【讨论】:

      【解决方案4】:

      秘诀在于:

      DBGrid1.DataSource.Enabled:=False; ...进行更改... DBGrid1.DataSource.Enabled:=True;

      用 D5Pro 测试

      【讨论】:

        猜你喜欢
        • 2015-03-01
        • 1970-01-01
        • 2012-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-28
        • 1970-01-01
        相关资源
        最近更新 更多