2016-09-23 3 views
0

データソースのデータセットプロパティが実行時に設定されている場合、TStringGrid以外のコントロールをライブバインドで正しく動作させるにはどうすればよいですか?私はデータセットフィールドを認識するためにTStringGridを取得できますが、TEditなどの他のコントロールは認識できません。実行時にdatasource.datasetを設定するときに、TEditをライブバインディングの下で​​データセットに接続できない

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

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

+0

「使用」とは、使用セクションの1つにファイルを追加することを意味し、「使用しない」とは、削除したことを意味します。 – joeb545

+0

"use"とは、実装の下のusesセクションにファイルを追加することを意味し、 "unuse"はファイルを削除したことを意味します。私はインターフェイスにプログラミングしています。フォームには、フォームが作成された直後に設定するViewModelというインターフェイスプロパティがあります。 ViewModelのsetプロシージャには、Datasource.Dataset:= ViewModel.Datasetというコードがあります。データソースは既にBindSourceDbにアタッチされています。データ認識アプリケーションでこれを実行していた場合、データソースに接続されているすべてのコントロールが自動的に接続され、データが入力されます。この作業をLivebindingsで行うにはどうすればよいですか? – joeb545

答えて

0

次のプロジェクトは、私にとってLiveBindingを使用してうまく動作します。私は私 はあなたがすなわち

  • 、initally DataModuleのユニットDynDMuを使用するフォームユニット、DynLiveBindingsuを記述するために理解するものでした。その状態で ライブバインディングコンポーネントをフォームに追加し、 からBindingListオブジェクトを作成し、それを使用してTLinkGridToDataSourceおよびTLinkControlToFieldを追加し、それらのプロパティを設定することで、フォームに「バインド」コンポーネントを追加しました。

  • はその後、私は、フォームの使用方法の一覧からDynDMuへの参照を削除 をコンパイルし、プロジェクトを実行し、StringList1とEDIT1が正しくDataModuleので データセットにバインドされています。明らかに

私はあなたのプロジェクトがそう 、あなたは問題を得ている理由はわかりませんが、少なくともこの答えはあなたにあなたと 比較の基準として使用するための作業プロジェクトを与える見ることができません。

TDataSourceがデータモジュールまたはフォームのいずれにも含まれていないことに注意してください。

私はDelphi Seattle、btwを使用しています。

DataModuleの:

unit DynDMu; 
[...] 
type 
    TDataModule1 = class(TDataModule) 
    CDS1: TClientDataSet; 
    CDS1Name: TStringField; 
    CDS1ID: TIntegerField; 
    procedure DataModuleCreate(Sender: TObject); 
    end; 

[...] 

procedure TDataModule1.DataModuleCreate(Sender: TObject); 
begin 
    CDS1.CreateDataSet; 
    CDS1.InsertRecord([1, 'One']); 
    CDS1.InsertRecord([2, 'Two']); 
    CDS1.InsertRecord([3, 'Three']); 
end; 

フォームユニット

unit DynLiveBindingsu; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.Bind.EngExt, 
    Vcl.Bind.DBEngExt, Vcl.Bind.Grid, System.Rtti, System.Bindings.Outputs, 
    Vcl.Bind.Editors, Data.Bind.Components, Data.Bind.DBScope, Data.Bind.Grid, 
    Data.DB, Vcl.StdCtrls, Vcl.Grids, Data.Bind.Controls, Vcl.ExtCtrls, 
    Vcl.Buttons, Vcl.Bind.Navigator; 

type 
    TForm1 = class(TForm) 
    StringGrid1: TStringGrid; 
    Edit1: TEdit; 
    BindingsList1: TBindingsList; 
    LinkGridToDataSource1: TLinkGridToDataSource; 
    BindSourceDB1: TBindSourceDB; 
    BindNavigator1: TBindNavigator; 
    LinkControlToField1: TLinkControlToField; 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

end. 

フォームDFM

object Form1: TForm1 
[...] 
    object StringGrid1: TStringGrid 
    [...] 
    end 
    object Edit1: TEdit 
    [...] 
    end 
    object BindNavigator1: TBindNavigator 
    Left = 16 
    Top = 150 
    Width = 240 
    Height = 25 
    DataSource = BindSourceDB1 
    Orientation = orHorizontal 
    TabOrder = 2 
    end 
    object BindingsList1: TBindingsList 
    Methods = <> 
    OutputConverters = <> 
    Left = 216 
    Top = 184 
    object LinkGridToDataSource1: TLinkGridToDataSource 
     Category = 'Quick Bindings' 
     DataSource = BindSourceDB1 
     GridControl = StringGrid1 
     Columns = < 
     item 
      MemberName = 'ID' 
     end 
     item 
      MemberName = 'Name' 
     end> 
    end 
    object LinkControlToField1: TLinkControlToField 
     Category = 'Quick Bindings' 
     DataSource = BindSourceDB1 
     FieldName = 'Name' 
     Control = Edit1 
     Track = False 
    end 
    end 
    object BindSourceDB1: TBindSourceDB 
    DataSet = DataModule1.CDS1 
    ScopeMappings = <> 
    Left = 296 
    Top = 184 
    end 
end 
+0

@ joeb545:自分のプロジェクトがなぜ機能しないのか分かりましたか? – MartynA

0

マーティン、

これは私の質問に対応していませんでした。私はdatamoduleユニットを自分のusesセクションに配置したくありませんでした。代わりにdatasource.datasetを設定してデータセットを「注入」したいと思っていました。

私は解決策を見つけることができました。これは、データセットプロパティが設定された後で、その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とFD接続。私はそれらを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. 
関連する問題