簡體   English   中英

如何刷新 TListView 和 TFDMemTable 的實時綁定?

[英]How to refresh Livebinding for TListView and TFDMemTable?

我有一個與 TFDMemTable 實時綁定的 TListView。 我還有一個 TButton,它在 TFDMemTable 上添加了該項目,在添加項目后,它顯然顯示在 TListView 中。 TListView 位於 TTabControl 的 TTabItem 之一中。

我的問題是,當我在運行時更改選項卡並返回 TListView 選項卡添加更多項目時,添加更多項目后,先前顯示的數據將變為空。

我可以確認 TFDMemTable 中的數據仍然完整,包括新添加的數據。

我懷疑需要刷新實時綁定才能將所有數據返回到 TListView。

有沒有人知道如何在運行時刷新實時綁定?

PS我希望上面能清楚地解釋我的問題。 否則,如果您需要更多詳細信息,請告訴我。

更新 1:最小可重復示例

這是我可以為 MRE 做的最少的事情,不是我案例的確切情況,但應該是相同的問題。 在 TabItem2 上添加列表后您會注意到,然后返回 TabItem1 在列表中添加更多項目,列表中現有的詳細信息將消失。

FMX程序

unit TabbedFormwithNavigation;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TabControl, FMX.StdCtrls, FMX.Controls.Presentation,
  FMX.Gestures, System.Actions, FMX.ActnList, FMX.ListView.Types,
  FMX.ListView.Appearances, FMX.ListView.Adapters.Base, REST.Types,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
  Fmx.Bind.DBEngExt, Data.Bind.Components, Data.Bind.DBScope, Data.DB,
  FireDAC.Comp.DataSet, FireDAC.Comp.Client, REST.Response.Adapter, REST.Client,
  Data.Bind.ObjectScope, FMX.ListView;

type
  TTabbedwithNavigationForm = class(TForm)
    TabControl1: TTabControl;
    TabItem1: TTabItem;
    TabItem2: TTabItem;
    GestureManager1: TGestureManager;
    ActionList1: TActionList;
    NextTabAction1: TNextTabAction;
    PreviousTabAction1: TPreviousTabAction;
    lsv1: TListView;
    rsc1: TRESTClient;
    rsq1: TRESTRequest;
    rsp1: TRESTResponse;
    rsd1: TRESTResponseDataSetAdapter;
    mtb1: TFDMemTable;
    bdr1: TBindSourceDB;
    bdl1: TBindingsList;
    lsv2: TListView;
    rsc2: TRESTClient;
    rsq2: TRESTRequest;
    rsp2: TRESTResponse;
    rsd2: TRESTResponseDataSetAdapter;
    mtb2: TFDMemTable;
    bdr2: TBindSourceDB;
    lcf1: TLinkListControlToField;
    btn1: TButton;
    lsv3: TListView;
    mtb3: TFDMemTable;
    strngfldmtb3brandname: TStringField;
    strngfldmtb3brand: TStringField;
    bdr3: TBindSourceDB;
    lcf3: TLinkListControlToField;
    lcf2: TLinkListControlToField;
    pnl1: TPanel;
    lbl1: TLabel;
    pnl2: TPanel;
    lbl2: TLabel;
    pnl3: TPanel;
    lbl3: TLabel;
    procedure GestureDone(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
    procedure lsv1ItemClick(const Sender: TObject; const AItem: TListViewItem);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  TabbedwithNavigationForm: TTabbedwithNavigationForm;

implementation

{$R *.fmx}

procedure TTabbedwithNavigationForm.btn1Click(Sender: TObject);
var
  brandname : string;
begin
  brandname := mtb2.Lookup('name', lsv2.Items[lsv2.ItemIndex].Text, 'name');
//  ShowMessage(lsv2.Items[lsv2.ItemIndex].Text);
  if mtb3.Locate('brandname', brandname, []) = False then
  begin
    mtb3.DisableControls;
    mtb3.Append;
    mtb3.FieldByName('brandname').AsString := brandname;
    mtb3.EnableControls;
    mtb3.Post;
  end;
end;

procedure TTabbedwithNavigationForm.FormCreate(Sender: TObject);
begin
  { This defines the default active tab at runtime }
  TabControl1.ActiveTab := TabItem1;

  rsq1.Execute;
end;

procedure TTabbedwithNavigationForm.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
  if Key = vkHardwareBack then
  begin
    if (TabControl1.ActiveTab = TabItem1) then
    begin
      Key := 0;
    end;
  end;
end;

procedure TTabbedwithNavigationForm.GestureDone(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
  case EventInfo.GestureID of
    sgiLeft:
      begin
        if TabControl1.ActiveTab <> TabControl1.Tabs[TabControl1.TabCount - 1] then
          TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex + 1];
        Handled := True;
      end;

    sgiRight:
      begin
        if TabControl1.ActiveTab <> TabControl1.Tabs[0] then
          TabControl1.ActiveTab := TabControl1.Tabs[TabControl1.TabIndex - 1];
        Handled := True;
      end;
  end;
end;

procedure TTabbedwithNavigationForm.lsv1ItemClick(const Sender: TObject;
  const AItem: TListViewItem);
var
  SearchItem : String;
begin
  //place the equivalent api for the meta click
  SearchItem := lsv1.Items[lsv1.ItemIndex].Text;
  rsc2.BaseURL := 'https://nm5c906csg.execute-api.ap-southeast-1.amazonaws.com/v0/dbqueries?search-item=' + SearchItem;

  //execute api request for the searches
  rsq2.Execute;
  TabControl1.TabIndex := 1;
end;

end.

FMX文件

object TabbedwithNavigationForm: TTabbedwithNavigationForm
  Left = 0
  Top = 0
  Caption = 'Form56'
  ClientHeight = 596
  ClientWidth = 405
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  OnCreate = FormCreate
  OnKeyUp = FormKeyUp
  DesignerMasterStyle = 0
  object TabControl1: TTabControl
    Touch.GestureManager = GestureManager1
    OnGesture = GestureDone
    Align = Client
    FullSize = True
    Size.Width = 405.000000000000000000
    Size.Height = 596.000000000000000000
    Size.PlatformDefault = False
    TabHeight = 49.000000000000000000
    TabIndex = 1
    TabOrder = 0
    TabPosition = PlatformDefault
    Sizes = (
      405s
      547s
      405s
      547s)
    object TabItem1: TTabItem
      CustomIcon = <
        item
        end>
      IsSelected = False
      Size.Width = 201.000000000000000000
      Size.Height = 49.000000000000000000
      Size.PlatformDefault = False
      StyleLookup = 'tabitemfavorites'
      TabOrder = 0
      Text = 'TabItem1'
      ExplicitSize.cx = 101.000000000000000000
      ExplicitSize.cy = 49.000000000000000000
      object lsv1: TListView
        ItemAppearanceClassName = 'TListItemAppearance'
        ItemEditAppearanceClassName = 'TListItemShowCheckAppearance'
        HeaderAppearanceClassName = 'TListHeaderObjects'
        FooterAppearanceClassName = 'TListHeaderObjects'
        ItemIndex = 0
        Align = Client
        Size.Width = 405.000000000000000000
        Size.Height = 487.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        OnItemClick = lsv1ItemClick
      end
      object pnl1: TPanel
        Align = Top
        Size.Width = 405.000000000000000000
        Size.Height = 60.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 1
        object lbl1: TLabel
          Align = Client
          StyledSettings = [Family, FontColor]
          Margins.Left = 60.000000000000000000
          Margins.Right = 60.000000000000000000
          Size.Width = 285.000000000000000000
          Size.Height = 60.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.Font.StyleExt = {00070000000000000004000000}
          TextSettings.HorzAlign = Center
          Text = 'Please select an item here to filter out items for TabItem2.'
          TabOrder = 0
        end
      end
    end
    object TabItem2: TTabItem
      CustomIcon = <
        item
        end>
      IsSelected = True
      Size.Width = 202.000000000000000000
      Size.Height = 49.000000000000000000
      Size.PlatformDefault = False
      StyleLookup = 'tabitemcontacts'
      TabOrder = 0
      Text = 'TabItem2'
      ExplicitSize.cx = 102.000000000000000000
      ExplicitSize.cy = 49.000000000000000000
      object lsv2: TListView
        ItemAppearanceClassName = 'TImageListItemBottomDetailAppearance'
        ItemEditAppearanceClassName = 'TImageListItemBottomDetailShowCheckAppearance'
        HeaderAppearanceClassName = 'TListHeaderObjects'
        FooterAppearanceClassName = 'TListHeaderObjects'
        ItemIndex = 0
        Align = Top
        Position.Y = 60.000000000000000000
        Size.Width = 405.000000000000000000
        Size.Height = 221.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
      end
      object btn1: TButton
        Align = Top
        StyledSettings = [Family, FontColor]
        Position.Y = 281.000000000000000000
        Size.Width = 405.000000000000000000
        Size.Height = 40.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 1
        Text = 'SELECT'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.Font.StyleExt = {00070000000000000004000000}
        OnClick = btn1Click
      end
      object lsv3: TListView
        ItemAppearanceClassName = 'TImageListItemBottomDetailAppearance'
        ItemEditAppearanceClassName = 'TImageListItemBottomDetailShowCheckAppearance'
        HeaderAppearanceClassName = 'TListHeaderObjects'
        FooterAppearanceClassName = 'TListHeaderObjects'
        Align = Client
        Size.Width = 405.000000000000000000
        Size.Height = 166.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 2
      end
      object pnl2: TPanel
        Align = Top
        Size.Width = 405.000000000000000000
        Size.Height = 60.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 3
        object lbl2: TLabel
          Align = Client
          StyledSettings = [Family, FontColor]
          Margins.Left = 30.000000000000000000
          Margins.Right = 30.000000000000000000
          Size.Width = 345.000000000000000000
          Size.Height = 60.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.Font.StyleExt = {00070000000000000004000000}
          TextSettings.HorzAlign = Center
          Text = 
            'Select an item below then click the "SELECT" button to list down' +
            ' the items selected.'
          TabOrder = 0
        end
      end
      object pnl3: TPanel
        Align = Bottom
        Position.Y = 487.000000000000000000
        Size.Width = 405.000000000000000000
        Size.Height = 60.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 4
        object lbl3: TLabel
          Align = Client
          StyledSettings = [Family]
          Size.Width = 405.000000000000000000
          Size.Height = 60.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.StyleExt = {00070000000000000004000000}
          TextSettings.FontColor = claRed
          TextSettings.HorzAlign = Center
          Text = 
            'The error comes when you go back to TabItem1 and select another ' +
            'item, the existing details on the list will be gone.'
          TabOrder = 0
        end
      end
    end
  end
  object GestureManager1: TGestureManager
    Sensitivity = 80.000000000000000000
    Left = 48
    Top = 185
    GestureData = <
      item
        Control = TabControl1
        Collection = <
          item
            GestureID = sgiLeft
          end
          item
            GestureID = sgiRight
          end>
      end>
  end
  object ActionList1: TActionList
    Left = 48
    Top = 120
    object NextTabAction1: TNextTabAction
      Category = 'Tab'
    end
    object PreviousTabAction1: TPreviousTabAction
      Category = 'Tab'
    end
  end
  object rsc1: TRESTClient
    Accept = 'application/json, text/plain; q=0.9, text/html;q=0.8,'
    AcceptCharset = 'utf-8, *;q=0.8'
    BaseURL = 
      'https://bs3winlz02.execute-api.ap-southeast-1.amazonaws.com/v0/d' +
      'bqueries'
    Params = <>
    Left = 136
    Top = 120
  end
  object rsq1: TRESTRequest
    Client = rsc1
    Params = <>
    Response = rsp1
    SynchronizedEvents = False
    Left = 136
    Top = 184
  end
  object rsp1: TRESTResponse
    ContentType = 'application/json'
    Left = 136
    Top = 248
  end
  object rsd1: TRESTResponseDataSetAdapter
    Active = True
    Dataset = mtb1
    FieldDefs = <>
    Response = rsp1
    Left = 136
    Top = 312
  end
  object mtb1: TFDMemTable
    Active = True
    FieldDefs = <
      item
        Name = 'meta'
        DataType = ftWideString
        Size = 255
      end>
    IndexDefs = <>
    FetchOptions.AssignedValues = [evMode]
    FetchOptions.Mode = fmAll
    ResourceOptions.AssignedValues = [rvSilentMode]
    ResourceOptions.SilentMode = True
    UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
    UpdateOptions.CheckRequired = False
    UpdateOptions.AutoCommitUpdates = True
    StoreDefs = True
    Left = 136
    Top = 376
  end
  object bdr1: TBindSourceDB
    DataSet = mtb1
    ScopeMappings = <>
    Left = 136
    Top = 440
  end
  object bdl1: TBindingsList
    Methods = <>
    OutputConverters = <>
    Left = 20
    Top = 5
    object lcf1: TLinkListControlToField
      Category = 'Quick Bindings'
      DataSource = bdr1
      FieldName = 'meta'
      Control = lsv1
      FillExpressions = <>
      FillHeaderExpressions = <>
      FillBreakGroups = <>
    end
    object lcf3: TLinkListControlToField
      Category = 'Quick Bindings'
      DataSource = bdr3
      FieldName = 'brandname'
      Control = lsv3
      FillExpressions = <
        item
          SourceMemberName = 'brand'
          ControlMemberName = 'Detail'
        end>
      FillHeaderExpressions = <>
      FillBreakGroups = <>
    end
    object lcf2: TLinkListControlToField
      Category = 'Quick Bindings'
      DataSource = bdr2
      FieldName = 'name'
      Control = lsv2
      FillExpressions = <
        item
          SourceMemberName = 'brand'
          ControlMemberName = 'Detail'
        end>
      FillHeaderExpressions = <>
      FillBreakGroups = <>
    end
  end
  object rsc2: TRESTClient
    Accept = 'application/json, text/plain; q=0.9, text/html;q=0.8,'
    AcceptCharset = 'utf-8, *;q=0.8'
    BaseURL = 
      'https://nm5c906csg.execute-api.ap-southeast-1.amazonaws.com/v0/d' +
      'bqueries?search-item=sage'
    Params = <>
    Left = 200
    Top = 120
  end
  object rsq2: TRESTRequest
    Client = rsc2
    Params = <>
    Response = rsp2
    SynchronizedEvents = False
    Left = 200
    Top = 184
  end
  object rsp2: TRESTResponse
    ContentType = 'application/json'
    Left = 200
    Top = 248
  end
  object rsd2: TRESTResponseDataSetAdapter
    Active = True
    Dataset = mtb2
    FieldDefs = <>
    Response = rsp2
    Left = 200
    Top = 312
  end
  object mtb2: TFDMemTable
    Active = True
    FieldDefs = <
      item
        Name = 'brand'
        DataType = ftWideString
        Size = 255
      end
      item
        Name = 'name'
        DataType = ftWideString
        Size = 255
      end
      item
        Name = 'description'
        DataType = ftWideString
        Size = 255
      end>
    IndexDefs = <>
    FetchOptions.AssignedValues = [evMode]
    FetchOptions.Mode = fmAll
    ResourceOptions.AssignedValues = [rvSilentMode]
    ResourceOptions.SilentMode = True
    UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
    UpdateOptions.CheckRequired = False
    UpdateOptions.AutoCommitUpdates = True
    StoreDefs = True
    Left = 200
    Top = 376
  end
  object bdr2: TBindSourceDB
    DataSet = mtb2
    ScopeMappings = <>
    Left = 200
    Top = 440
  end
  object mtb3: TFDMemTable
    Active = True
    FetchOptions.AssignedValues = [evMode]
    FetchOptions.Mode = fmAll
    ResourceOptions.AssignedValues = [rvSilentMode]
    ResourceOptions.SilentMode = True
    UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
    UpdateOptions.CheckRequired = False
    UpdateOptions.AutoCommitUpdates = True
    Left = 264
    Top = 376
    object strngfldmtb3brandname: TStringField
      FieldName = 'brandname'
      Size = 200
    end
    object strngfldmtb3brand: TStringField
      FieldKind = fkLookup
      FieldName = 'brand'
      LookupDataSet = mtb2
      LookupKeyFields = 'name'
      LookupResultField = 'brand'
      KeyFields = 'brandname'
      Size = 200
      Lookup = True
    end
  end
  object bdr3: TBindSourceDB
    DataSet = mtb3
    ScopeMappings = <>
    Left = 264
    Top = 440
  end
end

錯誤在於我在 FDMemTable (mtb3) 中創建的 LookUp 字段。 我避開了那些。 相反,我創建了一個普通的數據字段,並直接從 TListView (lsv2) 中獲取數據,如下所示:

FMX程序

procedure TTabbedwithNavigationForm.btn1Click(Sender: TObject);
var
  brandname, brand : string;
begin
  brandname := mtb2.Lookup('name', lsv2.Items[lsv2.ItemIndex].Text, 'name');
  brand := mtb2.Lookup('name', lsv2.Items[lsv2.ItemIndex].Text, 'brand');

  if mtb3.Locate('brandname', brandname, []) = False then
  begin
    mtb3.DisableControls;
    mtb3.Append;
    mtb3.FieldByName('brandname').AsString := brandname;
    mtb3.FieldByName('brand').AsString := brand;           //manually coded instead of lookup field in the fdmemtable (mtb3)
    mtb3.EnableControls;
    mtb3.Post;
  end;
end;

FMX文件

  object mtb3: TFDMemTable
    Active = True
    FieldDefs = <
      item
        Name = 'brandname'
        DataType = ftString
        Size = 200
      end
      item
        Name = 'brand'
        DataType = ftString        // defined as data instead of lookup
        Size = 100
      end>
    IndexDefs = <>
    FetchOptions.AssignedValues = [evMode]
    FetchOptions.Mode = fmAll
    ResourceOptions.AssignedValues = [rvSilentMode]
    ResourceOptions.SilentMode = True
    UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates]
    UpdateOptions.CheckRequired = False
    UpdateOptions.AutoCommitUpdates = True
    StoreDefs = True
    Left = 264
    Top = 376
    object strngfldmtb3brandname: TStringField
      FieldName = 'brandname'
      Size = 200
    end
    object strngfldmtb3brand: TStringField
      FieldName = 'brand'
      Size = 100
    end
  end
  1. Crie e instâncie um TFDMemTable temporário (FDMemTableTemporario)

  2. 進口 os registros do TFDMemTable original para o temporário

FDMemTableTemporario.AppendData(FDMemTambleOriginal);

  1. Feche o TFDMemTable 原版

FDMemTambleOriginal.Close;

  1. 進口 os registros do TFDMemTable temporario para o original

FDMemTambleOriginal.AppendData(FDMemTableTemporario);

  1. 阿雷格里斯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM