Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用'关闭WPF窗口时的确认;X';按钮或ESC键_C#_Wpf - Fatal编程技术网

C# 使用'关闭WPF窗口时的确认;X';按钮或ESC键

C# 使用'关闭WPF窗口时的确认;X';按钮或ESC键,c#,wpf,C#,Wpf,单击“X”按钮或按ESC键关闭桌面应用程序中的WPF窗口时,如何请求确认? 我想用最少的代码来完成它。 类似的问题存在于MVVM灯上,代码太多。利用onclose虚拟方法: protected override void OnClosing(CancelEventArgs e) { // show the message box here and collect the result // if you want to stop it, set e.Cancel = true

单击“X”按钮或按ESC键关闭桌面应用程序中的WPF窗口时,如何请求确认?
我想用最少的代码来完成它。

类似的问题存在于MVVM灯上,代码太多。

利用
onclose
虚拟方法:

protected override void OnClosing(CancelEventArgs e)
{
    // show the message box here and collect the result

    // if you want to stop it, set e.Cancel = true
    e.Cancel = true;
}
该内部代码可能如下所示:

var result = MessageBox.Show(...);

if (result == DialogResult.{SomeEnumVal}) { e.Cancel = true; }
AI发现了依附行为的IMHO。添加此功能的目的是只向窗口标记添加一个名称空间和一个属性:

main window.xaml

<Window x:Class="WpfClosingByEscape.MainWindow"
    ...
    xmlns:bhv="clr-namespace:WpfClosingByEscape.Behaviors"
    bhv:WindowClosingBehavior.Enabled="True"
    >
...
</Window>
public bool ShouldCloseApp { get; private set; }

private RelayCommand<Window> _exitApplicationCommand;

public RelayCommand<Window> ExitApplicationCommand
{
    get
    {
        if (_exitApplicationCommand == null)
        {
            _exitApplicationCommand = new RelayCommand<Window>(exitApplicationCommand);
        }

        return _exitApplicationCommand;
    }
}

/// <summary>
/// This closes a specified window.  If you pass the main window, then this application 
/// will exit.  This is because the application shut down mode is set to OnMainWindowClose.
/// </summary>
/// <param name="window">The window to close.</param>
private void exitApplicationCommand(Window window)
{
    try
    {
        DialogService.ShowConfirmation(
            UIStrings.MainWindowViewModel_ExitProgramHeader,
            UIStrings.MainWindowViewModel_ExitProgramMessage,
            UIStrings.MainWindowViewModel_ExitProgramAcceptText,
            UIStrings.MainWindowViewModel_ExitProgramCancelText,
            (DialogResult result) =>
            {
                if ((result.Result.HasValue) && (result.Result.Value))
                {
                    if (ElectroTekManager.Manager.ConnectedElectroTek != null)
                    {
                        SendToStatusOperation operation = new SendToStatusOperation(ElectroTekManager.Manager.ConnectedElectroTek, (operationResult, errorMessage) =>
                        {
                            if (operationResult != FirmwareOperation.OperationResult.Success)
                            {
                                log.Debug(string.Format("{0} {1}", CautionStrings.MainWindowViewModel_LogMsg_UnableToSendToStatus, errorMessage));
                            }
                            else if (!string.IsNullOrEmpty(errorMessage))
                            {
                                log.Debug(errorMessage);
                            }

                            Application.Current.Dispatcher.Invoke(new Action(() => closeApp(window)));
                        });

                        operation.Execute();
                    }
                    else
                    {
                        closeApp(window);
                    }
                }
            });
    }
    catch (Exception ex)
    {
        log.Debug(CautionStrings.MainWindowViewModel_LogMsg_FailedToShowConfirmation, ex);
    }
}

/// <summary>
/// Closes the application.
/// </summary>
/// <param name="window">The window.</param>
private void closeApp(Window window)
{
    ShouldCloseApp = true;

    Dispose();

    Application.Current.Shutdown();
}

我一直在寻找一种更具MVVM的方法。这就是对我有效的方法

窗口代码

<Window x:Class="My.Namespace.Wpf.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    mc:Ignorable="d" 
    Closing="Window_Closing">
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Closing">
        <i:InvokeCommandAction Command="{Binding ExitApplicationCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

隐藏的代码

/// <summary>
/// Handles the Closing event of the Window control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    e.Cancel = !_viewModel.ShouldCloseApp;
}
//
///处理窗口控件的关闭事件。
/// 
///事件的来源。
///包含事件数据的实例。
私有无效窗口\u关闭(对象发送方,System.ComponentModel.CancelEventArgs e)
{
e、 取消=!\u viewModel.ShouldCloseApp;
}
视图模型中的命令

<Window x:Class="WpfClosingByEscape.MainWindow"
    ...
    xmlns:bhv="clr-namespace:WpfClosingByEscape.Behaviors"
    bhv:WindowClosingBehavior.Enabled="True"
    >
...
</Window>
public bool ShouldCloseApp { get; private set; }

private RelayCommand<Window> _exitApplicationCommand;

public RelayCommand<Window> ExitApplicationCommand
{
    get
    {
        if (_exitApplicationCommand == null)
        {
            _exitApplicationCommand = new RelayCommand<Window>(exitApplicationCommand);
        }

        return _exitApplicationCommand;
    }
}

/// <summary>
/// This closes a specified window.  If you pass the main window, then this application 
/// will exit.  This is because the application shut down mode is set to OnMainWindowClose.
/// </summary>
/// <param name="window">The window to close.</param>
private void exitApplicationCommand(Window window)
{
    try
    {
        DialogService.ShowConfirmation(
            UIStrings.MainWindowViewModel_ExitProgramHeader,
            UIStrings.MainWindowViewModel_ExitProgramMessage,
            UIStrings.MainWindowViewModel_ExitProgramAcceptText,
            UIStrings.MainWindowViewModel_ExitProgramCancelText,
            (DialogResult result) =>
            {
                if ((result.Result.HasValue) && (result.Result.Value))
                {
                    if (ElectroTekManager.Manager.ConnectedElectroTek != null)
                    {
                        SendToStatusOperation operation = new SendToStatusOperation(ElectroTekManager.Manager.ConnectedElectroTek, (operationResult, errorMessage) =>
                        {
                            if (operationResult != FirmwareOperation.OperationResult.Success)
                            {
                                log.Debug(string.Format("{0} {1}", CautionStrings.MainWindowViewModel_LogMsg_UnableToSendToStatus, errorMessage));
                            }
                            else if (!string.IsNullOrEmpty(errorMessage))
                            {
                                log.Debug(errorMessage);
                            }

                            Application.Current.Dispatcher.Invoke(new Action(() => closeApp(window)));
                        });

                        operation.Execute();
                    }
                    else
                    {
                        closeApp(window);
                    }
                }
            });
    }
    catch (Exception ex)
    {
        log.Debug(CautionStrings.MainWindowViewModel_LogMsg_FailedToShowConfirmation, ex);
    }
}

/// <summary>
/// Closes the application.
/// </summary>
/// <param name="window">The window.</param>
private void closeApp(Window window)
{
    ShouldCloseApp = true;

    Dispose();

    Application.Current.Shutdown();
}
public bool应该关闭app{get;private set;}
专用中继命令_exitApplicationCommand;
public RelayCommand exitapplication命令
{
得到
{
if(_exitApplicationCommand==null)
{
_exitApplicationCommand=新的RelayCommand(exitApplicationCommand);
}
返回_exitApplicationCommand;
}
}
/// 
///这将关闭指定的窗口。如果您通过主窗口,则此应用程序
///将退出。这是因为应用程序关闭模式设置为OnMainWindowClose。
/// 
///窗户关上了。
私有void exitApplicationCommand(窗口)
{
尝试
{
DialogService.ShowConfirmation(
UIStrings.MainWindowViewModel_ExitProgramHeader,
UIStrings.MainWindowViewModel\u ExitProgramMessage,
UIStrings.MainWindowViewModel\u ExitProgramAcceptText,
UIStrings.MainWindowViewModel\u ExitProgramCancelText,
(DialogResult结果)=>
{
if((result.result.HasValue)&&(result.result.Value))
{
if(ElectroTekManager.Manager.ConnectedElectroTek!=null)
{
SendToStatusOperation=新的SendToStatusOperation(Electronitekmanager.Manager.ConnectedElectroTek,(operationResult,errorMessage)=>
{
if(operationResult!=FirmwareOperation.operationResult.Success)
{
log.Debug(string.Format(“{0}{1}”,CautionStrings.MainWindowViewModel_LogMsg_UnableToSendToStatus,errorMessage));
}
如果(!string.IsNullOrEmpty(errorMessage))为else
{
调试日志(错误消息);
}
Application.Current.Dispatcher.Invoke(新操作(()=>closeApp(窗口));
});
operation.Execute();
}
其他的
{
关闭应用程序(窗口);
}
}
});
}
捕获(例外情况除外)
{
log.Debug(CautionStrings.MainWindowViewModel\u LogMsg\u失败到OWConfirmation,ex);
}
}
/// 
///关闭应用程序。
/// 
///窗户。
私有void closeApp(窗口)
{
ShouldCloseApp=true;
处置();
Application.Current.Shutdown();
}

确认后,我调用Application.Current.Shutdown()。这将再次触发代码隐藏中的关闭事件,但不会再次触发退出命令。

感谢您的回答,但没有ESC键处理。我找到了单独的解决方案,以防止关闭问题和ESC处理。我想要一体化解决方案和最少的编码:)@ofadjs,你是说你想让ESC能够关闭表单吗?我想不管关闭表单所用的方法是什么,ONCLOSE get都会被调用。@BillGregg,这是正确的<当窗体试图关闭时,无论发生什么情况,都会调用code>OnClosing。@neoistheone,yes,窗口必须以两种方式关闭。