NativeUIPIckerView add items function in datamodule

Hello,

I am adding items to a NativeUIPIckerView using a little procedure which is just doing that.
Calling the procedure from the form with the UIPicker in it the procedure runs fine.
Calling the same procedure from a data module leaves the UIPicker empty.
I already checked, the procedure is called correctly from my data module.
In fact it is in a procedure which is called when a thread terminates.

Best regards

Mirko

Threading and GUI related stuff never go hand in hand without proper synchronization. Did you apply the proper threading code synchronization to the GUI?

https://docwiki.embarcadero.com/CodeExamples/Sydney/en/ThreadSynchronize_(Delphi)

I think so.

I am using this code in my thread:

try
    DM1.FTP1.Connect;
    try
      try
        DM1.FTP1.ChangeDir(ftpdirectory);
        for i := 0 to filestosync.Count-1 do
        begin
          DM1.Ftp1.Get(filestosync[i],TPath.Combine(TPath.GetTempPath, filestosync[i]),True,false);
          TTilesPlanningLoadThread.Synchronize(nil,
          procedure
          begin
            TILESPLANNINGFORM.PBAR.Value := i+1;
            DM1.SQLITEQUERY.Close;
            DM1.SQLITEQUERY.SQL.Text := 'DELETE from files_to_sync WHERE FS_CSITEID = ''tilesplanning'' AND FS_FILENAME = ''' + filestosync[i] + ''';';
            DM1.SQLITEQUERY.Execute;
            TFile.Copy(TPath.Combine(TPath.GetTempPath, filestosync[i]), TPath.Combine(csiteplanningpath, filestosync[i]), True);
            TFile.Delete(TPath.Combine(TPath.GetTempPath, filestosync[i]));
          end);
        end;
      except
      end;
    finally
      DM1.FTP1.Disconnect;
      TTilesPlanningLoadThread.Synchronize(nil,
      procedure
      begin
        TILESPLANNINGFORM.PBAR.Visible := false;

        HIST.Columns[0].Items.Clear;
        HIST.SelectRowInColumn(0,0,false); //To clear the display

       DM1.SQLITEQUERY.Close;
       DM1.SQLITEQUERY.SQL.Text := 'SELECT * from consite_planning ORDER BY PLANNING_DATE desc';
       DM1.SQLITEQUERY.Execute;

       HIST.BeginUpdate;
       while not DM1.SQLITEQUERY.EOF do
       begin
         pitem := HIST.Columns[0].Items.Add;
         if DM1.SQLITEQUERY.FieldByName('PLANNING_VALID').AsInteger = -1 then
      pitem.Text := 'KW ' + 
 
InttoStr(WeekoftheYear(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger))) +
                    ' ' + 
    DateTimetoStr(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger))
    else
      pitem.Text := 'VALIDIEREN - KW ' + InttoStr(WeekoftheYear(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger))) +
                    ' ' + DateTimetoStr(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger));
    DM1.SQLITEQUERY.Next;
  end;
  HIST.EndUpdate;

        DM1.SQLITEQUERY.First;
        TILESPLANNINGFORM.LoadPDF(TPath.Combine(csiteplanningpath, DM1.SQLITEQUERY.FieldByName('PLANNING_FILE').AsString), DM1.SQLITEQUERY.FieldByName('PLANNING_ORIGID').AsString, DM1.SQLITEQUERY.FieldByName('PLANNING_VALID').AsInteger);
      end);
      DM1.UniConnection1.Disconnect;
      filestosync.Free;
    end;
  except
  end;

At first sight the code seems to look ok, but unfortunately it's not possible for us to tell exactly what is going on without a full working sample.

Hi Pieter,

the procedure is well executed and finds 12 records.
The only thing is that the NativeUIPickerView does not seem to be painted correctly.

After my procedure:

HIST.BeginUpdate;
while not DM1.SQLITEQUERY.EOF do
begin
  pitem := HIST.Columns[0].Items.Add;
  if DM1.SQLITEQUERY.FieldByName('PLANNING_VALID').AsInteger = -1 then
  pitem.Text := 'KW ' +  InttoStr(WeekoftheYear(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger))) +
                    ' ' + DateTimetoStr(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger))
  else
    pitem.Text := 'VALIDIEREN - KW ' + InttoStr(WeekoftheYear(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger))) +
                  ' ' + DateTimetoStr(UnixToDateTime(DM1.SQLITEQUERY.FieldByName('PLANNING_DATE').AsInteger));
  DM1.SQLITEQUERY.Next;
end;
HIST.EndUpdate;

I added a ShowMessage to show me the columns count and the items count in Column[0].
The result was correct so I recon that the control is not painted correctly.

By the way... calling the same procedure from the form where the NativeUiPickerView resides gives me a correct result.
May be that there is a problem when using a datamodule? Because that's where the thread is execute.

Rgds

Mirko

An idea would be to capture the results of your query in a separate data structure, pass it to the form where the picker is and then load that data inside the picker instead of accessing the picker from the data module. Either way, the data has to be synchronized to the main form thread so that might be a way around this issue.

On the same form I got a TMSFMXNativePDFDocument which is also loading a pdf correctly in the last sync part of the thread so it is correctly synchronised and the data is passed to the main form.
Is there any chance that I can debug this to look where the control is not reacting correctly?

Rgds

Mirko

It's unclear exactly, the TTMSFMXNativePDFDocument is a complete different component. The TTMSFMXNativeUIPickerView will actually serve the items virtually, which means that it will call a couple of delegated methods. It could be possible that the delegate methods is disturbed because it's being called from another thread.