- Konu sahibi
- #1
İşlem, formun kapanmasını
Uygulama, herhangi bir alanın değiştiğini kendiliğinden her zaman bilemez. Bu nedenle formda bir
Form üzerindeki değişiklik üreten kontrollerin
Bir veritabanı uygulamasında değişiklik durumunu ayrıca veri kümesinden de alabilirsiniz. Örneğin düzenlenen kayıt için
Formun
Bu olay form kapanmadan önce çalışır.
Örneğin yönteminizin iskeleti şu şekilde olabilir:
Bu örnekteki kayıt bölümü uygulamanın kendi veri erişim koduyla değiştirilmelidir. Gerçek kayıt işlemi tamamlanmadan
Yeni belge açıldığında, mevcut belge kaydedildiğinde veya değişiklikler bilinçli olarak iptal edilip eski durum geri yüklendiğinde
Veritabanı kullanılan formlarda kayıt başarılı olduğunda veri kümesini
En güvenli akış şudur: değişiklik oluştuğunda bayrağı ayarlayı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ı
| Durum | CanClose sonucu | Anlamı |
|---|---|---|
| Değişiklik yok | True | Kullanıcıdan onay istenmeden kapanmaya izin verilir. |
| Kaydet ve kayıt başarılı | True | Değişiklikler saklanmıştır; form kapanabilir. |
| Kaydetme başarısız | False | Kapanma durdurulur; hata giderildikten sonra yeniden kaydetmek gerekir. |
| Kaydetmeden çık | True | Form kapanır ve mevcut değişiklikler bilerek göz ardı edilir. |
| İptal | False | Kullanı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.