Arif

WFN Üye
Konular
638
Mesajlar
638
Çözüm
0
Ticaret Puanı
0
Üyelik
23 Gün
Konum
Bilecik
Web Sitesi
Var
Alanı
SEO Uzmanı
1/1
Konu sahibi
İşlem, formun kapanmasını OnCloseQuery olayında durdurup uygulamanın değişiklik durumunu kontrol etmektir. Değişiklik varsa kullanıcıya kaydetme, kaydetmeden çıkma veya kapatmayı iptal etme seçenekleri gösterilir. Kullanıcı kaydetmeyi seçtiğinde kayıt başarılıysa kapanmaya izin verilir; kayıt başarısızsa veya iptal edilirse form açık kalır.

Kapanma kontrolü için değişiklik durumunu tutun​


Uygulama, herhangi bir alanın değiştiğini kendiliğinden her zaman bilemez. Bu nedenle formda bir FChanged değişkeni tutup kullanıcı veri değiştirdiğinde bunu True yapabilirsiniz. Örneğin metin alanlarının OnChange olayında ortak bir yöntem çağırın:

Kod:
type
  TForm1 = class(TForm)
    EditName: TEdit;
    MemoDescription: TMemo;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure DocumentChanged(Sender: TObject);
  private
    FChanged: Boolean;
    procedure MarkChanged;
    function SaveDocument: Boolean;
  end;

procedure TForm1.MarkChanged;
begin
  FChanged := True;
end;

procedure TForm1.DocumentChanged(Sender: TObject);
begin
  MarkChanged;
end;

Form üzerindeki değişiklik üreten kontrollerin OnChange olayını DocumentChanged yöntemine bağlayın. Böylece EditName veya MemoDescription içeriği değiştiğinde formun kaydedilmemiş durumda olduğu anlaşılır.

Bir veritabanı uygulamasında değişiklik durumunu ayrıca veri kümesinden de alabilirsiniz. Örneğin düzenlenen kayıt için DataSet.Modified değeri True ise kayıt üzerinde henüz kaydedilmemiş bir değişiklik vardır. Formdaki belge değişiklikleriyle veri kümesi değişikliklerini birlikte kontrol etmek gerekir; yalnızca ekrandaki bir TEdit değişkenine bakmak, veritabanı düzenlemelerini kaçırabilir.

OnCloseQuery içinde kullanıcıdan karar alın​


Formun OnCloseQuery olayına şu mantığı uygulayın. Aşağıdaki örnek SaveDocument yönteminin kayıt işlemini başarıyla tamamladığında True, hata oluştuğunda veya kayıt tamamlanamadığında False döndürdüğü varsayımsal bir örnektir.

Kod:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  Answer: Integer;
begin
  CanClose := True;

  if not FChanged then
    Exit;

  Answer := MessageDlg(
    'Kaydedilmemiş değişiklikler var. Kaydetmek istiyor musunuz?',
    mtConfirmation,
    [mbYes, mbNo, mbCancel],
    0
  );

  case Answer of
    mrYes:
      begin
        CanClose := SaveDocument;

        if CanClose then
          FChanged := False;
      end;

    mrNo:
      begin
        CanClose := True;
      end;

    mrCancel:
      begin
        CanClose := False;
      end;
  end;
end;

Bu olay form kapanmadan önce çalışır. CanClose değeri False bırakılırsa pencere kapanmaz. Kullanıcı İptal seçeneğini seçtiğinde veya kaydetme işlemi başarısız olduğunda bu sonuç gerekir; aksi durumda kullanıcı değişikliklerini fark etmeden kaybedebilir.

Sonuçların anlamı​

DurumCanClose sonucuAnlamı
Değişiklik yokTrueKullanıcıdan onay istenmeden kapanmaya izin verilir.
Kaydet ve kayıt başarılıTrueDeğişiklikler saklanmıştır; form kapanabilir.
Kaydetme başarısızFalseKapanma durdurulur; hata giderildikten sonra yeniden kaydetmek gerekir.
Kaydetmeden çıkTrueForm kapanır ve mevcut değişiklikler bilerek göz ardı edilir.
İptalFalseKullanıcı belge üzerinde çalışmaya devam eder.

Kaydetme başarısız olduğunda formu kapatmayın​


SaveDocument içinde veritabanı kaydı, dosya yazma veya doğrulama işlemini yapın. İşlem başarısızsa kullanıcıya hata gösterip False döndürün. Böylece OnCloseQuery kapanmayı engeller. Kayıt başarılı olduktan sonra FChanged := False atanmalıdır; bunu kayıt işleminden önce yapmak, hata oluştuğunda değişiklik yokmuş gibi davranılmasına neden olur.

Örneğin yönteminizin iskeleti şu şekilde olabilir:

Kod:
function TForm1.SaveDocument: Boolean;
begin
  Result := False;

  try
    { Alanları doğrulayın. }
    { Veritabanı kaydını veya dosya yazma işlemini yapın. }
    { İşlem başarılıysa burada Result := True yapın. }
    Result := True;
  except
    on E: Exception do
      MessageDlg('Kayıt yapılamadı: ' + E.Message, mtError, [mbOK], 0);
  end;
end;

Bu örnekteki kayıt bölümü uygulamanın kendi veri erişim koduyla değiştirilmelidir. Gerçek kayıt işlemi tamamlanmadan Result := True döndürmeyin. Kullanıcı Kaydetmeden çık seçeneğini seçtiğinde ise kayıt yapılmaz ve form kapanır; bu seçim, verilerin kaydedildiğini değil, kullanıcının değişiklikleri gözden çıkardığını gösterir.

Değişiklik bayrağını doğru zamanda sıfırlayın​


Yeni belge açıldığında, mevcut belge kaydedildiğinde veya değişiklikler bilinçli olarak iptal edilip eski durum geri yüklendiğinde FChanged := False yapın. Bir belge yüklendikten sonra yükleme sırasında tetiklenen OnChange olayları bayrağı yanlışlıkla True yapıyorsa, yükleme tamamlandıktan sonra bayrağı açıkça sıfırlayın.

Veritabanı kullanılan formlarda kayıt başarılı olduğunda veri kümesini Post etmek, yeni kayıtta Append veya Insert sonrasında oluşan düzenleme durumunu sonlandırmak ve ardından kendi değişiklik bayrağını sıfırlamak gerekir. Sadece ekrandaki alanların değişmediğini kontrol etmek, veri kümesinin Edit durumunu veya henüz Post edilmemiş bir kaydı göstermeyebilir.

En güvenli akış şudur: değişiklik oluştuğunda bayrağı ayarlayın, OnCloseQuery içinde yalnızca bayrak açıkken soru sorun, kaydetme sonucunu mutlaka kontrol edin ve ancak başarılı kayıttan sonra kapanmaya izin verin. Böylece Kaydet seçeneği gerçek kayıt başarısını, Kaydetmeden çık seçeneği bilinçli veri kaybını, İptal seçeneği ise kapanma işleminin durdurulduğunu açıkça ifade eder.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic