MSDN CloseReason.UserClosing
에서 사용자가 양식을 닫기로 결정한 것을 알았지 만 X 단추를 클릭하거나 닫기 단추를 클릭하는 것이 동일하다고 생각합니다. 그렇다면 내 코드에서이 둘을 어떻게 구별 할 수 있습니까?
모두 감사합니다.
답변
WinForms를 요청한다고 가정하면 FormClosing () 이벤트를 사용할 수 있습니다 . FormClosing () 이벤트는 양식이 닫힐 때마다 트리거됩니다.
사용자가 X 또는 CloseButton을 클릭했는지 감지하려면 보낸 사람 개체를 통해 가져올 수 있습니다. 보낸 사람을 Button 컨트롤로 캐스팅하고 예를 들어 “CloseButton”이라는 이름을 확인합니다.
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.
}
그렇지 않으면 MDIContainerForm을 닫기 전에 모든 MdiChildren을 닫거나 저장되지 않은 변경 사항을 확인하는 이벤트와 같이 FormClosing 이벤트에 대해 특정 작업을 수행하기를 원했기 때문에 X 또는 CloseButton을 클릭했는지 구분할 필요가 없었습니다. 이러한 상황에서 우리는 두 버튼을 구별 할 필요가 없습니다.
ALT+로 닫으면 F4FormClosing () 이벤트가 트리거되어 닫으라는 메시지를 Form에 보냅니다. 이벤트를 취소 할 수 있습니다.
FormClosingEventArgs.Cancel = true.
이 예에서 이것은
e.Cancel = true.
FormClosing () 및 FormClosed () 이벤트 의 차이점을 확인하십시오 .
FormClosing은 양식이 닫힐 메시지를 수신 할 때 발생하며 닫히기 전에 할 일이 있는지 확인합니다.
FormClosed는 양식이 실제로 닫힐 때 발생하므로 닫힌 후에 발생합니다.
도움이 되나요?
답변
CloseReason
당신은 MSDN에서 발견 열거 형은 사용자가 응용 프로그램을 폐쇄하거나 종료에 기인하거나 등의 작업 관리자에 의해 폐쇄 여부를 확인하기위한 목적입니다 …
이유에 따라 다음과 같은 다른 작업을 수행 할 수 있습니다.
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
}
하지만 짐작했듯이 x 버튼을 클릭하거나 작업 표시 줄을 마우스 오른쪽 버튼으로 클릭하고 ‘닫기’를 클릭하거나를 누르는 것 사이에는 차이가 없습니다 Alt F4. 모두 CloseReason.UserClosing
이유가 있습니다.
답변
“X”버튼이 등록 DialogResult.Cancel
되므로 다른 옵션은 DialogResult
.
양식에 여러 개의 단추가있는 경우 이미 DialogResult
각 단추에 서로 다른을 연결하고있을 가능성 이 있으며 이는 각 단추의 차이점을 구분할 수있는 수단을 제공합니다.
(예 : 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;
}
}
}
답변
X 버튼을 클릭하거나 Close()
코드 를 호출하여 양식이 닫혔는지 감지하는 방법은 무엇입니까?
사용자가 제목 표시 줄에서 X 버튼을 클릭하거나 Alt + F4를 사용하여 양식을 닫거나 시스템 메뉴를 사용하여 양식을 닫거나 양식이 Close()
메서드 를 호출하여 닫히기 때문에 양식 닫기 이벤트 인수의 닫기 이유에 의존 할 수 없습니다. 위의 경우 종료 이유 는 원하지 않는 결과가 사용자에 의해 종료됩니다 .
양식이 X 단추 또는 Close
방법으로 닫혔는지 구별하려면 다음 옵션 중 하나를 사용할 수 있습니다.
- 플래그
WM_SYSCOMMAND
를 처리 하고 확인SC_CLOSE
하고 설정합니다. StackTrace
프레임에Close
메소드 호출이 포함되어 있는지 확인하십시오 .
예 1-핸들 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()");
}
예 2-StackTrace 확인
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");
}
답변
양식이 닫힌 경우 애플리케이션을 닫을시기를 결정합니다 (애플리케이션이 특정 양식에 첨부되지 않은 경우).
private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (Application.OpenForms.Count == 0) Application.Exit();
}
답변
내 응용 프로그램에서 항상 종료 버튼, alt + f4 또는 다른 양식 닫기 이벤트 에서 alt + x를 포착하는 Form Close 메서드를 사용합니다 . 내 모든 클래스에는 mstrClsTitle = "grmRexcel"
이 경우에 Private 문자열 로 정의 된 클래스 이름 이 있습니다.이 경우 Form Closing 메서드와 Form Closing 메서드를 호출하는 Exit 메서드가 있습니다. Form Closing Method에 대한 설명도 있습니다.this.FormClosing = My Form Closing Form Closing method name
.
이것에 대한 코드 :
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;
}
}
}
}
}
답변
다음과 같이 디자인에서 이벤트 처리기를 추가해 볼 수 있습니다. 디자인보기에서 폼 열기, 속성 창 열기 또는 F4 키, 이벤트 도구 모음 버튼을 클릭하여 폼 개체에서 이벤트보기, 동작 그룹에서 FormClosing 이벤트 찾기, 두 번 클릭. 참조 : https://social.msdn.microsoft.com/Forums/vstudio/en-US/9bdee708-db4b-4e46-a99c-99726fa25cfb/how-do-i-add-formclosing-event?forum=csharpgeneral