MSDN'de CloseReason.UserClosing
, kullanıcının formu kapatmaya karar verdiğini öğrendim ama sanırım hem X düğmesine hem de kapat düğmesine tıklamak için aynı şey geçerli. Öyleyse, kodumda bu ikisini nasıl ayırt edebilirim?
Hepinize teşekkürler.
MSDN'de CloseReason.UserClosing
, kullanıcının formu kapatmaya karar verdiğini öğrendim ama sanırım hem X düğmesine hem de kapat düğmesine tıklamak için aynı şey geçerli. Öyleyse, kodumda bu ikisini nasıl ayırt edebilirim?
Hepinize teşekkürler.
Yanıtlar:
WinForms istediğinizi varsayarsak, FormClosing () olayını kullanabilirsiniz . FormClosing () olayı, bir formun kapatılması gerektiğinde tetiklenir.
Kullanıcının X'i mi yoksa CloseButton'ınızı mı tıklattığını tespit etmek için, bunu gönderen nesnesi üzerinden alabilirsiniz. Göndereni bir Düğme kontrolü olarak atmaya çalışın ve örneğin "CloseButton" adını doğrulayın.
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
if (string.Equals((sender as Button).Name, @"CloseButton"))
// Do something proper to CloseButton.
else
// Then assume that X has been clicked and act accordingly.
}
Aksi takdirde, MDIContainerForm'u kapatmadan önce tüm MdiChildren'leri kapatmak veya kaydedilmemiş değişiklikler için olay denetimi gibi FormClosing olayında belirli bir şey gerçekleştirmek istediğimden, X veya CloseButton'ın tıklanıp tıklanmadığını hiçbir zaman ayırt etmem gerekmedi. Bu koşullar altında, bana göre, iki düğmeden de ayırt etmemize gerek yok.
ALT+ F4İle kapatma aynı zamanda FormClosing () olayını tetikler, çünkü Form'a kapatılmasını söyleyen bir mesaj gönderir. Etkinliği ayarlayarak iptal edebilirsiniz.
FormClosingEventArgs.Cancel = true.
Örneğimizde bu, şu şekilde tercüme edilir:
e.Cancel = true.
FormClosing () ve FormClosed () olayları arasındaki farka dikkat edin .
FormClosing, form kapatılacak mesajı aldığında ve kapatılmadan önce yapması gereken bir şey olup olmadığını doğruladığında gerçekleşir.
FormClosed, form gerçekten kapatıldığında, bu nedenle kapatıldıktan sonra gerçekleşir.
Bu yardımcı olur mu?
CloseReason
Eğer MSDN üzerinde bulunan numaralandırma sadece kullanıcının uygulamayı kapalı ya da bir kapatma kaynaklandığını veya vb görev yöneticisi tarafından kapatılmış olup olmadığını kontrol etmek amacıyla bir ...
Nedenine göre farklı eylemler yapabilirsiniz, örneğin:
void Form_FormClosing(object sender, FormClosingEventArgs e)
{
if(e.CloseReason == CloseReason.UserClosing)
// Prompt user to save his data
if(e.CloseReason == CloseReason.WindowsShutDown)
// Autosave and clear up ressources
}
Ancak tahmin ettiğiniz gibi, x düğmesine tıklamakla görev çubuğuna sağ tıklamakla 'kapat'a tıklamak ya da basmak Alt F4vb. Arasında hiçbir fark yoktur CloseReason.UserClosing
.
"X" düğmesi kaydedildiği DialogResult.Cancel
için başka bir seçenek de DialogResult
.
Formunuzda birden çok düğme varsa, muhtemelen zaten DialogResult
her biriyle farklı ' ler ilişkilendiriyorsunuzdur ve bu, size her düğme arasındaki farkı anlamanız için araçlar sağlayacaktır.
(Örnek: btnSubmit.DialogResult = DialogResult.OK
, btnClose.DialogResult = Dialogresult.Abort
)
public Form1()
{
InitializeComponent();
this.FormClosing += Form1_FormClosing;
}
/// <summary>
/// Override the Close Form event
/// Do something
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
{
//In case windows is trying to shut down, don't hold the process up
if (e.CloseReason == CloseReason.WindowsShutDown) return;
if (this.DialogResult == DialogResult.Cancel)
{
// Assume that X has been clicked and act accordingly.
// Confirm user wants to close
switch (MessageBox.Show(this, "Are you sure?", "Do you still want ... ?", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
{
//Stay on this form
case DialogResult.No:
e.Cancel = true;
break;
default:
break;
}
}
}
DialogResult
kalır None
. Sorun ne olabilir?
X
markaları DialogResult
ihtiva Cancel
değil None
. Düğmenize atamak None
, .DialogResult
özelliğini hiç ayarlamamakla aynıdır ve form.Close()
düğmenizin olay işleyicisinden ararsanız , düğmeyi form.DialogResult
içerir Cancel
. Tüm form kapatma düğmelerinizden başka None
veya Cancel
bunlara yalnızca bir değer atamak , istediğiniz ayrımı yapmanıza olanak tanır.
Close()
kodla arayarak kapanıp kapanmadığı nasıl anlaşılır ?Form kapatma olay bağımsız değişkenlerinin yakın nedenine güvenemezsiniz, çünkü kullanıcı başlık çubuğundaki X düğmesine tıklarsa veya Alt + F4 kullanarak formu kapatırsa veya formu kapatmak için sistem menüsünü kullanırsa veya formu çağırarak kapatılırsa Close()
, tümü Yukarıdaki durumlarda, yakın sebep Kullanıcı Tarafından Kapatılacak ve bu da arzu edilmeyen bir sonuç olacaktır.
Formun X düğmesiyle mi yoksa Close
yöntemle mi kapatıldığını ayırt etmek için aşağıdaki seçeneklerden birini kullanabilirsiniz:
WM_SYSCOMMAND
, kontrol edin SC_CLOSE
ve bayrak koyunStackTrace
Çerçevelerden herhangi birinin Close
yöntem çağrısı içerip içermediğini kontrol edin .Örnek 1 - Tanıtıcı WM_SYSCOMMAND
public bool ClosedByXButtonOrAltF4 {get; private set;}
private const int SC_CLOSE = 0xF060;
private const int WM_SYSCOMMAND = 0x0112;
protected override void WndProc(ref Message msg)
{
if (msg.Msg == WM_SYSCOMMAND && msg.WParam.ToInt32() == SC_CLOSE)
ClosedByXButtonOrAltF4 = true;
base.WndProc(ref msg);
}
protected override void OnShown(EventArgs e)
{
ClosedByXButtonOrAltF4 = false;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (ClosedByXButtonOrAltF4)
MessageBox.Show("Closed by X or Alt+F4");
else
MessageBox.Show("Closed by calling Close()");
}
Örnek 2 - StackTrace'i Kontrol Etme
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (new StackTrace().GetFrames().Any(x => x.GetMethod().Name == "Close"))
MessageBox.Show("Closed by calling Close()");
else
MessageBox.Show("Closed by X or Alt+F4");
}
StackTrace()
ve sorunu çözdü.
Bir formun kapatılması durumunda başvurunun ne zaman kapatılacağını belirler (başvurunuz belirli bir forma eklenmemişse).
private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (Application.OpenForms.Count == 0) Application.Exit();
}
Uygulamalarımda her zaman çıkış Düğmemden alt + x'i yakalayan bir Form Kapatma yöntemi kullanıyorum, alt + f4 veya başka bir form kapatma etkinliği başlatıldı. Tüm sınıflarım, mstrClsTitle = "grmRexcel"
bu durumda Özel dize olarak tanımlanan sınıf adına , Form Kapatma Yöntemini ve Form Kapatma Yöntemini çağıran bir Çıkış yöntemine sahiptir. Ayrıca Form Kapatma Yöntemi için bir bildirimim var - this.FormClosing = My Form Closing Form Closing method name
.
Bunun kodu:
namespace Rexcel_II
{
public partial class frmRexcel : Form
{
private string mstrClsTitle = "frmRexcel";
public frmRexcel()
{
InitializeComponent();
this.FormClosing += frmRexcel_FormClosing;
}
/// <summary>
/// Handles the Button Exit Event executed by the Exit Button Click
/// or Alt + x
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
/// <summary>
/// Handles the Form Closing event
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmRexcel_FormClosing(object sender, FormClosingEventArgs e)
{
// ---- If windows is shutting down,
// ---- I don't want to hold up the process
if (e.CloseReason == CloseReason.WindowsShutDown) return;
{
// ---- Ok, Windows is not shutting down so
// ---- either btnExit or Alt + x or Alt + f4 has been clicked or
// ---- another form closing event was intiated
// *) Confirm user wants to close the application
switch (MessageBox.Show(this,
"Are you sure you want to close the Application?",
mstrClsTitle + ".frmRexcel_FormClosing",
MessageBoxButtons.YesNo, MessageBoxIcon.Question))
{
// ---- *) if No keep the application alive
//---- *) else close the application
case DialogResult.No:
e.Cancel = true;
break;
default:
break;
}
}
}
}
}
Aşağıdaki gibi tasarımdan olay işleyicisi eklemeyi deneyebilirsiniz: Formu tasarım görünümünde açın, özellikler penceresini açın veya F4'e basın, Form nesnesindeki olayları görüntülemek için olay araç çubuğu düğmesine tıklayın, Davranış grubunda FormClosing olayını bulun ve çift tıklayın. Referans: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9bdee708-db4b-4e46-a99c-99726fa25cfb/how-do-i-add-formclosing-event?forum=csharpgeneral
if (this.DialogResult == DialogResult.Cancel)
{
}
else
{
switch (e.CloseReason)
{
case CloseReason.UserClosing:
e.Cancel = true;
break;
}
}
Kullanıcı form üzerindeki 'X' düğmesini veya kapat düğmesini tıkladığında koşul yürütülürse. Diğer, kullanıcı başka herhangi bir amaçla Alt + f4'ü tıkladığında kullanılabilir
namespace Test
{
public partial class Member : Form
{
public Member()
{
InitializeComponent();
}
private bool xClicked = true;
private void btnClose_Click(object sender, EventArgs e)
{
xClicked = false;
Close();
}
private void Member_FormClosing(object sender, FormClosingEventArgs e)
{
if (xClicked)
{
// user click the X
}
else
{
// user click the close button
}
}
}
}
DialogResult
Daha açık çözüm olarak -Çözüme katılıyorum .
VB.NET yılında ise kalıplaştığı almak için gereklidir CloseReason
-property
Private Sub MyForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
Dim eCast As System.Windows.Forms.FormClosingEventArgs
eCast = TryCast(e, System.Windows.Forms.FormClosingEventArgs)
If eCast.CloseReason = Windows.Forms.CloseReason.None Then
MsgBox("Button Pressed")
Else
MsgBox("ALT+F4 or [x] or other reason")
End If
End Sub
Ayrıca formun "InitializeComponent ()" yönteminin içine kapanış işlevini de kaydetmem gerekiyordu:
private void InitializeComponent() {
// ...
this.FormClosing += FrmMain_FormClosing;
// ...
}
"FormClosing" işlevim verilen yanıta benziyor ( https://stackoverflow.com/a/2683846/3323790 ):
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) {
if (e.CloseReason == CloseReason.UserClosing){
MessageBox.Show("Closed by User", "UserClosing");
}
if (e.CloseReason == CloseReason.WindowsShutDown){
MessageBox.Show("Closed by Windows shutdown", "WindowsShutDown");
}
}
Belirtilmesi gereken bir şey daha var: "FormClosing" sonrasında ortaya çıkan bir "FormClosed" işlevi de vardır. Bu işlevi kullanmak için, aşağıda gösterildiği gibi kaydedin:
this.FormClosed += MainPage_FormClosed;
private void MainPage_FormClosing(object sender, FormClosingEventArgs e)
{
// your code after the form is closed
}