获取窗口显示对话框取消和关闭之间的区别

本文关键字:之间 区别 窗口 显示 对话框 取消 获取 | 更新日期: 2023-09-27 18:34:40

在我们的应用程序中,我们使用WPF和Caliburn Micro。我们使用自定义窗口管理器:

public class OurWindowManager : Caliburn.Micro.WindowManager
{
    protected override Window EnsureWindow(object model, object view, bool isDialog)
    {
        var window = base.EnsureWindow(model, view, isDialog);
        if (isDialog) window.ResizeMode = ResizeMode.NoResize;
        window.Icon = new BitmapImage(new Uri("pack://application:,,,/NWB.ico"));
        // TODO: Change to dynamic minWidth/minHeight based on window
        window.MinWidth = 600;
        new WindowSettingsBehavior().Attach(window);
        return window;
    }
}

在我们的代码中,我们主要使用这个窗口管理器,如下所示:

public void SomeMethod()
{
    var result = _windowManager.ShowDialog(new ConfirmDialogViewModel("some title",
        "some text"));
    if(result == true){ // if OK is pressed
        // do something on OK
    }
    // do nothing
}

在我最近的一种方法中,我想执行以下操作(在半伪代码中(:

public void SomeOtherMethod()
{
    _windowManager.ShowDialog(new ConfirmDialogViewModel("some title", "some text"));
    //if window is closed without pressing any of the buttons
        return; // do nothing
    //if OK is pressed {
        // do something on OK
    }
    // if Cancel is pressed: do something else
}

不幸的是,如果窗口关闭,ShowDialog 也会返回 false(即使 ShowDialog 返回一个可为空的布尔值 ( bool? ((。

所以,到目前为止,我所做的只是通过创建一个新Window-Behavior完全删除关闭按钮,并将其添加到if(isDialog)内的OurWindowManager类中:

if (isDialog)
{
    window.ResizeMode = ResizeMode.NoResize;
    new WindowHideBarBehavior().Attach(window);
}

这有效,我现在得到了一个只有标题的窗口,没有关闭 (X( 按钮。不幸的是,窗口仍然可以使用 Alt+F4 等关闭。我想过捕获 Alt+F4 并取消关闭,但由于 Alt+F4 是标准的 Window 行为,我认为用户不会非常欣赏它,而且我发现用户禁用它有点不直观。

所以,我的问题:我怎样才能完成上面提到的伪代码SomeOtherMethod。有没有办法区分关闭对话框或取消对话框。(注意:如上所述,请记住,我们使用Caliburn.Micro.WindowManager,而不是默认的 C# WPF 。不知道是否有很多差异,但我想至少有一些差异。


编辑:

我也知道我可以抓住收盘事件并取消收盘:

window.Closing -= DisableDialogClosing;
if (isDialog)
{
    window.ResizeMode = ResizeMode.NoResize;
    new WindowHideBarBehavior().Attach(window);
    window.Closing += DisableDialogClosing;
}
...
private static void DisableDialogClosing(object sender, CancelEventArgs e)
{
    e.Cancel = true;
}

但是,当我希望它关闭时(例如,当按下取消/确定按钮时(,它也会取消关闭。也许我可以向这个被覆盖的关闭事件处理程序添加某种属性标志,但也许你们有其他建议来完成相同的结果。

获取窗口显示对话框取消和关闭之间的区别

如果您只是通过扩展Window类来实现自己的对话框Window,则可以满足您的要求。在自定义Window 中,可以处理 Closed 事件,并将 Window.DialogResult 属性设置为在这种情况下null。对于正常的OkCancel状态,只需将Click处理程序附加到这些Button,并将 Window.DialogResult 属性设置为true并相应地false

private void CustomDialogWindow_Close(object sender, RoutedEventArgs e)
{
    DialogResult = null;
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
    DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
    DialogResult = false;
}

然后,您可以像这样检查Window关闭状态:

if (CustomDialogWindow.DialogResult == null) DoSomethingUponDialogWindowClose();

您可以在 MSDN 上的以下页面中找到更多有用的信息:

对话框概述
窗口.对话框结果属性

在@Sinatr的建议下,我在我的ConfirmDialogViewModel中添加了一个ClosedBy属性:

(之前(:

public sealed class ConfirmDialogViewModel : Screen
{
    public ConfirmDialogViewModel(string title, string message)
    {
        DisplayName = title;
        Message = message;
    }
    public string Message { get; set; }
    public void Ok()
    {
        TryClose(true);
    }
    public void Cancel()
    {
        TryClose(false);
    }
}

(之后(:

public sealed class ConfirmDialogViewModel : Screen
{
    public ClosedBy CloseReason { get; private set; }
    public ConfirmDialogViewModel(string title, string message)
    {
        DisplayName = title;
        Message = message;
        CloseReason = ClosedBy.Other;
    }
    public string Message { get; set; }
    public void Ok()
    {
        CloseReason = ClosedBy.Ok;
        TryClose(true);
    }
    public void Cancel()
    {
        CloseReason = ClosedBy.Cancel;
        TryClose(false);
    }
}
public enum ClosedBy
{
    Other,
    Ok,
    Cancel
}

我现在这样使用它:

public void SomeOtherMethod()
{
    var confirmDialog = new ConfirmDialogViewModel("some title", "some text");
    var result = _windowManager.ShowDialog(confirmDialog);
    if(result == null || confirmDialog.CloseReason == ClosedBy.Other) return;
    if(result == true && confirmDialog.CloseReason == ClosedBy.Ok){
        // Do something on OK
    }
    // Do something on cancel
}

我仍然保留了删除关闭按钮的行为,并在if(isDialog)内的OurWindowManager中添加了window.ShowInTaskbar = false;