我有一个表单上有两个按钮“取消”和“确定”。在“取消”按钮的处理程序中,我做了我需要做的任何回滚,然后调用this.Close()
。在“确定”按钮的处理程序中,我做了我需要做的任何事情,然后调用this.Close()
。
所以我现在意识到用户也可以点击表单右上角的“X”图标来关闭表单。我应该像处理“取消”按钮一样对待它,但是我无法覆盖“X”按钮。我能做的最好的事情是为OnFormClosing
事件添加一个处理程序。
我仍然感到困惑,并且不确定处理这个问题的最佳方法是什么。表单也可以关闭还有许多其他原因(如ALT-F4或Windows关闭)我想将所有这些视为“取消”按钮。
但是,是否通过单击“X”,“关闭”(最终调用this.Close()
)或“确定”(最终调用this.Close()
)来关闭表单,{{ 1}}是相同的(e.CloseReason
),UserClosing
的值也是相同的,所以我无法区分。
如果表单因单击“确定”按钮以外的任何原因而关闭,那么实现回滚的最佳方法是什么?
答案 0 :(得分:2)
你只需要在你的OK按钮处理程序中设置一个布尔值,并检查你的OnFormClosing()覆盖中的布尔值,如下所示:
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (!this.isClosingViaOkButton)
{
// ...do your rollback here.
MessageBox.Show("Rolling back");
}
}
private void okButton_Click(object sender, EventArgs e)
{
// ...do your committing here.
this.isClosingViaOkButton = true;
this.Close();
}
private bool isClosingViaOkButton;
}
作为替代方案,您可以在OnFormClosing()中执行这两项操作,而不是在OK按钮处理程序中提交并在OnFormClosing()中回滚,如下所示:
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (this.isClosingViaOkButton)
{
// ...do your committing.
}
else
{
// ...do your rollback.
}
}
我自己更喜欢这种方法。
答案 1 :(得分:1)
你真的不需要CloseReason
,是吗?
private bool _closing;
private void Form1_FormClosing( object sender, FormClosingEventArgs e )
{
e.Cancel = !_closing; // prevent form from being closed
}
// inside OK and Cancel button handler
...
_closing = true;
Close();
答案 2 :(得分:0)
在某些表单中,我通过使用Win32函数隐藏X按钮来解决问题 - 不知道它是否适合您的情况,但代码如下。
/// <summary>
/// Win32 function to get window information
/// </summary>
/// <param name="hWnd">Window handle</param>
/// <param name="nIndex">Information to get</param>
/// <returns>Required Window Information</returns>
[DllImport("user32.dll")]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
/// <summary>
/// Code to get/set Style for window
/// </summary>
private const int GWL_STYLE = -16;
/// <summary>
/// System menu bit
/// </summary>
private const int WS_SYSMENU = 0x80000;
/// <summary>
/// Hide close button on window
/// </summary>
/// <param name="w">Window to set</param>
/// <remarks>Actually removes all of system menu from window title bar</remarks>
public static void HideCloseButton(Window w)
{
var hwnd = new WindowInteropHelper(w).Handle;
NativeMethods.SetWindowLong(hwnd, GWL_STYLE, NativeMethods.GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
/// <summary>
/// Show close button on window
/// </summary>
/// <param name="w">Window to set</param>
/// <remarks>Actually shows all of system menu from window title bar</remarks>
public static void ShowCloseButton(Window w)
{
var hwnd = new WindowInteropHelper(w).Handle;
NativeMethods.SetWindowLong(hwnd, GWL_STYLE, NativeMethods.GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
}