Delphi lama yang baik (dan buruk) mengajari kami cara "klasik" dalam membangun aplikasi karena cara kita menulis kode "di belakang" IDE.

Berdasarkan paradigma ini, beberapa waktu lalu saya membangun perpustakaan yang memungkinkan saya untuk menyimpan/memuat file GUI ke INI dengan satu baris kode.

LoadForm(FormName)

BAM! Itu dia! Tidak ada lagi file INI!

Perpustakaan hanya menyimpan properti "relevan". Misalnya, untuk TCheckBox ia hanya menyimpan properti Checked, bukan Color atau Top/Left. Tapi itu lebih dari cukup.

Menyimpan formulir tidak memiliki masalah. Namun, saya memiliki "masalah" selama inisialisasi aplikasi. Mereka tidak terlalu bermasalah, tetapi kode inisialisasi tidak begitu bagus/elegan.

Misalnya ketika saya menetapkan Checkbox1.Checked := True itu akan memicu acara OnClick (seandainya kotak centang tidak dicentang pada waktu desain). Tetapi menetapkan nilai False (secara alami) tidak akan memicu peristiwa OnClick.

Oleh karena itu, saya harus memanggil CheckBox1Click(Sender) secara manual setelah SaveForm(FormName) untuk memastikan bahwa kode apa pun yang ada di CheckBox1Click, akan diinisialisasi. Tapi ini menimbulkan masalah lain. CheckBox1Click(Sender) mungkin dipanggil dua kali selama aplikasi dimulai (sekali oleh SaveForm dan sekali saya saya, secara manual).

Tentu saja, secara teori logika program harus diletakkan di objek individu dan dipisahkan dari GUI. Tetapi bahkan jika kita melakukan ini, masalah inisialisasi tetap ada. Anda memuat properti objek dari disk dan Anda menetapkannya ke GUI. Ketika Anda menetapkan nilai apa pun yang Anda miliki di objek Anda ke Checkbox1, itu akan (atau tidak) memanggil CheckBox1Click(Sender) yang akan mengatur nilai kembali ke objek.

Saat memulai aplikasi:

procedure TForm.FormCreate (Sender: TObject);
begin
  LogicObject.Load(File); // load app logic
  Checkbox1.Checked := LogicObject.Checked; // assign object to GUI
end;

procedure TForm.CheckBox1Click(Sender: TObject);
begin
  LogicObject.Checked := Checkbox1.Checked; 
end;

Mungkin solusinya melibatkan penulisan hal-hal seperti ini untuk SETIAP kontrol pada formulir:

OldEvent := CheckBox1.OnClick;
CheckBox1.OnClick := Nil;
CheckBox1.Checked := something;
CheckBox1.OnClick := OldEvent;

Tidak elegan.

Pertanyaan:
Bagaimana Anda memecahkan masalah khusus ini ATAU apa pendekatan Anda saat menyimpan/memulihkan GUI ke/dari disk?

0
Migrate2Lazarus see my profile 10 Januari 2018, 12:52

1 menjawab

Jawaban Terbaik

Ini adalah salah satu hal yang mengganggu saya di beberapa komponen sejak awal. Yang saya tahu adalah 3 opsi, kecuali memisahkan GUI dan logika bisnis seperti yang dikatakan @David, yang tidak selalu merupakan opsi.

  1. Seperti yang Anda tulis di atas, selalu batalkan penetapan acara agar tidak terpicu
  2. Gunakan peristiwa yang tidak dipicu seperti OnMouseDown atau OnMouseUp
  3. Atau solusi serupa yang saya gunakan dan menurut saya paling elegan

Buat variabel global FormPreparing yang disetel selama inisialisasi dan periksa nilainya di awal kejadian seperti di bawah ini.

procedure TForm.FormCreate (Sender: TObject);
begin
  FormPreparing := True;
  try    
    LogicObject.Load(File); // load app logic
    Checkbox1.Checked := LogicObject.Checked; // assign object to GUI
  finally
    FormPreparing := False;
  end;
end;

procedure TForm.CheckBox1Click(Sender: TObject);
begin
  if FormPreparing then
    Exit;
  LogicObject.Checked := Checkbox1.Checked;
end;
2
Triber 10 Januari 2018, 11:02