delphifiremonkeymultilingualdelphi-12-athens

Translate dataset in fmx


I am working on a desktop application using fmx framework and I add multiple languages to it (I used Tlang component to do so ) to translate any label or text inside the application but I run to a unexpected behavior everything is getting translated correctly except the data that is called from database (I am using firedac component to connect to the database) It seems that the Tlang component doesn't effect the data displayed in the grid at all

What I was wanted to happen is to translate some of the data that are displayed in the grid after I call them from the table of the data base (for example I have a column that describe the condition of the product: good , damaged ,out of stock (EN ) The expected behavior is Good =bien , damaged = on dommage, out of stock = rapture de stock


Solution

  • The TLang component in Delphi's FMX framework is designed to localize static UI elements like labels, buttons, and captions. However, it does not automatically translate dynamic content such as strings fetched from a database and displayed in a grid (e.g., TFDMemTable, TStringGrid, etc.).

    If you're displaying product conditions like "Good", "Damaged", or "Out of stock" from a database, and expecting TLang to translate them to "Bien", "Endommagé", or "Rupture de stock" respectively, you'll need to handle this manually.


    The simple solution is to manually build a translation dictionary.

    You can intercept the data after it's loaded and apply translations using a lookup dictionary.

    1. Create a Translation Dictionary

    uses System.Generics.Collections;
    
    var
      TranslationDict: TDictionary<string, string>;
    

    Initialize it with your translations:

    TranslationDict := TDictionary<string, string>.Create;
    TranslationDict.Add('Good', 'Bien');
    TranslationDict.Add('Damaged', 'Endommagé');
    TranslationDict.Add('Out of stock', 'Rupture de stock');
    

    2. Translate After Fetching Data

    Hook into the AfterOpen event of your dataset (TFDQuery, TFDMemTable, etc.) and do something like this:

    procedure TForm1.FDQuery1AfterOpen(DataSet: TDataSet);
    begin
      DataSet.DisableControls;
      try
        DataSet.First;
        while not DataSet.Eof do
        begin
          if TranslationDict.ContainsKey(DataSet.FieldByName('Condition').AsString) then
          begin
            DataSet.Edit;
            DataSet.FieldByName('Condition').AsString := TranslationDict[DataSet.FieldByName('Condition').AsString];
            DataSet.Post;
          end;
          DataSet.Next;
        end;
      finally
        DataSet.EnableControls;
      end;
    end;
    

    Note: This approach modifies the original field. If you want to preserve the raw data, use a calculated field instead.