简体   繁体   English

获取Window ShowDialog取消和关闭之间的区别

[英]Get difference between Window ShowDialog cancel and close

In our app we use WPF and Caliburn Micro. 在我们的应用程序中,我们使用WPF和Caliburn Micro。 We use a custom WindowManager: 我们使用自定义的WindowManager:

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;
    }
}

In our code we mostly use this WindowManager like so: 在我们的代码中,我们主要像这样使用WindowManager:

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
}

In one of my recent methods I want to do the following (in semi pseudo-code): 在我最近的一种方法中,我想执行以下操作(半伪代码):

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
}

Unfortunately, ShowDialog also returns false if the Window is closed (even though the ShowDialog returns a Nullable bool ( bool? )). 不幸的是,如果关闭了窗口,ShowDialog也将返回false(即使ShowDialog返回一个Nullable bool( bool? ))。

So, what I did so far is just completely remove the Close Button by making a new Window-Behavior , and I've added it to the OurWindowManager class inside the if(isDialog) : 因此,到目前为止,我所做的只是通过创建一个新的Window-Behavior完全删除了“关闭按钮”,并将其添加到了if(isDialog)OurWindowManager类中:

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

This works, and I now got a Window with just a title, and without a Close (X) button. 这可行,现在我得到一个仅带有标题的窗口,并且没有关闭(X)按钮。 Unfortunately, the window can still be closed with Alt+F4 and such. 不幸的是,仍然可以使用Alt + F4等关闭窗口。 I thought about catching Alt+F4 and cancel the closing, but since Alt+F4 is standard Window behavior, I don't think users will appreciate it a lot and I find it a bit unintuitive for the users to disable it.. 我曾考虑过要捕获Alt + F4并取消关闭,但是由于Alt + F4是标准的Window行为,所以我认为用户不会对此非常满意,因此禁用它有点不直观。

So, my question: How can I accomplish the pseudo-code in SomeOtherMethod mentioned above. 所以,我的问题是:如何在上述SomeOtherMethod中完成伪代码。 Is there a way to get the difference between closing a Dialog or canceling a Dialog. 有没有办法得到关闭对话框或取消对话框之间的区别。 (NOTE: As mentioned above, keep in mind we use Caliburn.Micro.WindowManager , not the default C# WPF one. Don't know if there are a lot of differences, but I guess there are at least some.) (注意:如上所述,请记住,我们使用Caliburn.Micro.WindowManager ,而不是默认的C#WPF之一。不知道是否有很多差异,但我想至少有一些差异。)


EDIT: 编辑:

I also know I can catch the closing event and cancel the closing: 我也知道我可以捕获关闭事件并取消关闭:

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;
}

But then it also cancels the closing when I want it to close (for example when the Cancel/OK button is pressed). 但是,当我希望关闭时(例如,当按下“取消/确定”按钮时),它也会取消关闭。 Maybe I can add some kind of Property-flag to this overridden Closing-EventHandler, but perhaps you guys/girls have other suggestions to accomplish the same results. 也许我可以向此重写的Closing-EventHandler中添加某种Property-flag,但是也许你们有其他建议来实现相同的结果。

You can fulfil your requirements if you just implement your own dialog Window by extending the Window class. 如果仅通过扩展Window类来实现自己的对话框Window ,就可以满足您的要求。 From inside your custom Window , you can handle the Closed event and set the Window.DialogResult property to null in that case. 在这种情况下,您可以从自定义Window内部处理Closed事件,并将Window.DialogResult属性设置为null For the normal Ok and Cancel states, you can simply attach Click handlers to those Button s and set the Window.DialogResult property to true and false accordingly. 对于正常的OkCancel状态,只需将Click处理程序附加到这些Button然后将Window.DialogResult属性分别设置为truefalse

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;
}

You could then check for the Window closed state like this: 然后,您可以像下面这样检查Window关闭状态:

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

You can find further helpful information in the following pages on MSDN: 您可以在MSDN的以下页面中找到更多有用的信息:

Dialog Boxes Overview 对话框概述
Window.DialogResult Property Window.DialogResult属性

After @Sinatr 's suggestion I've added a ClosedBy property to my ConfirmDialogViewModel: @Sinatr的建议之后,我向我的ConfirmDialogViewModel添加了ClosedBy属性:

(before): (之前):

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);
    }
}

(after): (后):

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
}

And I now use it like so: 现在,我像这样使用它:

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
}

I still kept the behavior to remove the close button, and also added window.ShowInTaskbar = false; 我仍然保留删除关闭按钮的行为,并且还添加了window.ShowInTaskbar = false; to the OurWindowManager inside the if(isDialog) . OurWindowManager内侧if(isDialog)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM