0

Datasource の Dataset プロパティが実行時に設定されている場合、TStringGrid 以外のコントロールを Livebinding で適切に動作させるにはどうすればよいですか? TStringGrid を取得してデータセット フィールドを認識させることはできますが、TEdit などの他のコントロールを取得することはできません。

ここに私のプロジェクトの詳細があります。データモジュールとフォームを作成しました。データセット オブジェクトとフォームを持つデータ モジュールには、UI コントロールと共にデータソースがあります。モジュール間の依存関係を減らすために、フォーム ユニットでデータモジュール ユニットを使用したくありません。むしろ、実行時に datasource.dataset を設定したいと思います。TStringGrid を使用すると、この戦略は機能しますが、TEdit では機能しません。LiveBinding でフィールドを手動で作成しようとしましたが、これらはデータセットにマップされません。VCL を使用していた場合、これは問題になりませんが、Livebindings でこれを実現する最善の方法を見つけることができませんでした。参考までに、これは FMX プロジェクトです。

また、データモジュールを「使用」して Livebinding 接続を作成し、その後それを使用しなかった場合、フィールドが BindSourceDb に表示されて読み取られる (無効) ことにも気付きました。アプリケーションを実行し、実行時にデータセット プロパティを設定すると、TEdit コントロールはフィールドを見つけて正常に動作します。モジュールを使用したり使用したりせずにこれを行う方法について何か提案はありますか?

4

2 に答える 2

0

マーティン、

これは私の質問に対処しませんでした。データモジュールユニットを uses セクションに配置したくありませんでした。代わりに、datasource.dataset を設定してデータセットを「注入」したかったのです。

解決策を見つけることができました。これには、linkControltoField1 プロパティの active プロパティを false に設定し、データセット プロパティの設定後に true に設定して、linkControltoField1 プロパティを「更新」する必要があります。これが私のコードです。(D10.1 ベルリン)

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rtti, System.Bindings.Outputs,
  Vcl.Bind.Editors, Data.Bind.EngExt, Vcl.Bind.DBEngExt, FireDAC.Stan.Intf,
  FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
  FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt,
  FireDAC.UI.Intf, FireDAC.VCLUI.Wait, FireDAC.Stan.Def, FireDAC.Stan.Pool,
  FireDAC.Phys, FireDAC.Phys.MSAcc, FireDAC.Phys.MSAccDef, Data.Bind.Controls,
  Vcl.ExtCtrls, Vcl.Buttons, Vcl.Bind.Navigator, Data.DB, FireDAC.Comp.Client,
  FireDAC.Comp.UI, FireDAC.Comp.DataSet, Data.Bind.Components, Vcl.StdCtrls,
  Data.Bind.DBScope, Data.Bind.ObjectScope, Vcl.Bind.Grid, Data.Bind.Grid,
  Vcl.Grids;

type
  TForm1 = class(TForm)
    BindSourceDB1: TBindSourceDB;
    Edit1: TEdit;
    BindingsList1: TBindingsList;
    DataSource1: TDataSource;
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    NavigatorBindSourceDB1: TBindNavigator;
    StringGrid1: TStringGrid;
    LinkGridToDataSourceBindSourceDB1: TLinkGridToDataSource;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    LinkControlToField1: TLinkControlToField;
    procedure Button1Click(Sender: TObject);
  private
    function GetDataset: Tdataset;
    procedure SetDataset(const Value: Tdataset);
    { Private declarations }
  public
    { Public declarations }
    property Dataset: Tdataset read GetDataset write SetDataset;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  BindSourceDb1.DataSource := DataSource1;
  LinkControlToField1.DataSource := BindSourceDB1;
  LinkControlToField1.Active := False;   //in order for this to work you must
  LinkControlToField1.Active := True;    // set link to false then to true

end;

function TForm1.GetDataset: Tdataset;
begin
  Result := Datasource1.DataSet;
end;

procedure TForm1.SetDataset(const Value: Tdataset);
begin
  Datasource1.DataSet := Value;
  BindSourceDb1.DataSource := DataSource1;
  LinkControlToField1.DataSource := BindSourceDB1;
  LinkControlToField1.Active := False;   //in order for this to work you must
  LinkControlToField1.Active := True;    // set link to false then to true
end;

end.

テキストの dfm ファイルを次に示します。

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 299
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 184
    Top = 88
    Width = 121
    Height = 21
    TabOrder = 0
  end
  object NavigatorBindSourceDB1: TBindNavigator
    Left = 280
    Top = 24
    Width = 240
    Height = 25
    DataSource = BindSourceDB1
    Orientation = orHorizontal
    TabOrder = 1
  end
  object StringGrid1: TStringGrid
    Left = 168
    Top = 112
    Width = 320
    Height = 120
    ColCount = 1
    FixedCols = 0
    RowCount = 2
    TabOrder = 2
    ColWidths = (
      64)
    RowHeights = (
      24
      24)
  end
  object Button1: TButton
    Left = 208
    Top = 256
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 3
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 352
    Top = 256
    Width = 75
    Height = 25
    Caption = 'Button2'
    TabOrder = 4
  end
  object Button3: TButton
    Left = 464
    Top = 256
    Width = 75
    Height = 25
    Caption = 'Button3'
    TabOrder = 5
  end
  object BindSourceDB1: TBindSourceDB
    ScopeMappings = <>
    Left = 432
    Top = 128
  end
  object BindingsList1: TBindingsList
    Methods = <>
    OutputConverters = <>
    Left = 20
    Top = 5
    object LinkGridToDataSourceBindSourceDB1: TLinkGridToDataSource
      Category = 'Quick Bindings'
      DataSource = BindSourceDB1
      GridControl = StringGrid1
      Columns = <>
    end
    object LinkControlToField1: TLinkControlToField
      Category = 'Quick Bindings'
      FieldName = 'LastName'
      Control = Edit1
      Track = True
    end
  end
  object DataSource1: TDataSource
    Left = 496
    Top = 184
  end
  object FDGUIxWaitCursor1: TFDGUIxWaitCursor
    Provider = 'Forms'
    Left = 384
    Top = 64
  end
end

データモジュールは目立たない。単純に FDTable と FDconnection です。それらを dbDemos データベースに添付しました。注意 Unit1 は Unit2 を使用しません。

unit Unit2;

interface

uses
  System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option,
  FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf,
  FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, FireDAC.UI.Intf,
  FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys, FireDAC.Phys.MSAcc,
  FireDAC.Phys.MSAccDef, FireDAC.VCLUI.Wait, Data.DB, FireDAC.Comp.Client,
  FireDAC.Comp.DataSet;

type
  TDataModule2 = class(TDataModule)
    FDTable1: TFDTable;
    FDConnection1: TFDConnection;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  DataModule2: TDataModule2;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

end.

最後に、プログラムユニットです。ここで、データセット プロパティを設定します。

program Project1;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {DataModule2: TDataModule};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TDataModule2, DataModule2);
  Application.CreateForm(TForm1, Form1);

  Form1.Dataset := Datamodule2.FDTable1;   //Injecting the dataset property

  Application.Run;
end.
于 2016-09-29T21:59:50.740 に答える