CombBox i Lista TStringList

0

Witam,
mam trzy comboboxy, która mają być wypełnione tymi samymi danymi czy jest możliwości ich odwołanie do jednej wspólnej listy typu tstringlist. Czy muszę aktualizować tą samą listę dla każdego komponentu?

0

Oczywiście

//var lista:TSringList;
  ComboBox1.Items.Assing(lista);
  ComboBox2.Items.Assing(lista);
  ComboBox2.Items.Assing(lista);
0

No właśnie chodzi mi o to, żeby tego nie robić. Żeby aktualizować wyłącznie listę a nie każdy combobox osobno.
Obrazowo:
Na starcie przypisuje listę do comboboxow

ComboBox1.Items.Assing(lista);
ComboBox2.Items.Assing(lista);
ComboBox3.Items.Assing(lista);

dodaję do listy element

lista.Items.Add('NewItem');

i chciałbym aby ta zmiana było widoczna we wszystkich comboboxach bez robienia kolejny raz

ComboBox1.Items.Assing(lista);
ComboBox2.Items.Assing(lista);
ComboBox3.Items.Assing(lista);

1

Tu raczej kariery nie zrobisz jedynie co to można by obsługiwać zdarzenie OnChange TStringList więc coś takiego:

  private
    { Private declarations }
    ls: TStringList;

    procedure ListaOnChange(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ListaOnChange(Sender: TObject);
begin
  ComboBox1.Items.Assign(ls);
  ComboBox2.Items.Assign(ls);
  ComboBox3.Items.Assign(ls);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ls:= TStringList.Create;
  ls.OnChange:= ListaOnChange;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ls.Free;
end;
0

Gdyby był sposób aby zamiast obiektu przypisać miejsce w pamięci do comboboxa to może by to zadziałało, ale albo nie ma takiej możliwość albo ( co jest akurat pewnikiem ) moja wiedza na ten temat jest zbyt mała. W każdym razie dziękuję wszystkim za pomoc.

0

Masz błąd w stopce; pełny cytat brzmi mniej-więcej tak:
Są tylko dwie rzeczy nieskończone wszechświat i ludzka głupota, chociaż co do pierwszego nie jestem pewien. ~Albert Einstein.

A cd.tego, to bez stworzenia własnej kontroli się nie obejdzie.

Fragment kodu TCustomComboBox (TComboBox dziedziczy po TCustomComboBox):

 TCustomComboBox = class(TCustomCombo)
  private
{ ... }
    FItems: TStringList;

TCustomCombo:

TCustomCombo = class(TCustomListControl)
  public
    property Items: TStrings read FItems write SetItems;
  end;

No i kod procedury SetItems:

procedure TCustomCombo.SetItems(const Value: TStrings);
begin
  if Assigned(FItems) then
    FItems.Assign(Value)
  else
    FItems := Value;
end;

Jeżeli byłoby samo przypisanie:

FItems := Value

Wtedy Value oraz FItems wskazywałyby na to samo miejsce w pamięci i to o czym mówisz byłoby możliwe.

Edit: jak widać, przypisanie jest także, gdy FItems jest równe nil.
Niestety, nie można wykonać Assign(nil); gdyby było to możliwe, można by zrobić obj.Assign(nil); obj.Assign(stringlist) i FItems wskazywałoby na stringlist, ale podczas wykonania Assign(nil) otrzymamy wyjątek Cannot assign nil to ....

0
procedure TCustomCombo.SetItems(const Value: TStrings);
begin
  if Assigned(FItems) then
    FItems.Assign(Value)
  else
    FItems := Value;
end;

Jak zwykle LCL/VCL usiłuje być mądrzejsze niż użytkownik. O ile w przypadku newbie powoduje to ułatwienie to w przypadku zaawansowanych konstrukcji już tak łatwo nie ma (por. Java i porównywanie stringów).

FItems := Value

Tja, przy okazji tracimy referencję do FItems które może być zainicjalizowane.

Najlepiej chyba zrobić swój obiekt dziedziczący z TStringList tak żeby miał listę ComboBox do zmiany i przy każdej zmianie zmieniał również wartości w tych ComboBox. W przypadku małej liczby zmian nie powinno być dużych utrat prędkości.

Patryk27 napisał(a):

Niestety, nie można wykonać Assign(nil); gdyby było to możliwe, można by zrobić obj.Assign(nil); obj.Assign(stringlist) i FItems wskazywałoby na stringlist, ale podczas wykonania Assign(nil) otrzymamy wyjątek Cannot assign nil to ....

Przecież Assign to konstruktor kopiujący, tak? Więc jaki sens ma wysyłanie mu nil? I czemu uważasz że danie obj.Assign(stringlist); spowoduje ustawienie FItems na stringlist. Mi się wydaje że to spowoduje ustawienie FItems na kopię stringlist. Jak gdzieś mam błąd w myśleniu to poprawcie, ekspertem z LCL nie jestem.

0

Zrobię to na razie w sposób prosty a później spróbuje bardziej finezyjne rozwiązania

 
//-----------------------------------------------------------------------------
// Lista ClientBoxow; Clients : List<TAdvComboBox>
procedure TDTM.AddClient(var Client: TAdvComboBox );
begin
  self.Clients.Add( Client );
end;
//-----------------------------------------------------------------------------
// Synchronizacja klientów w ComboBoxach;
procedure TDTM.SyncClient( ListClients : TStringList );
var i : integer;
begin
  for i := 0 to self.Clients.Count - 1 do
      self.Clients[i].Items.Assign( ListClients );
end;
//-----------------------------------------------------------------------------
```delphi
 

1 użytkowników online, w tym zalogowanych: 0, gości: 1