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

时间:2014-12-19 13:18:54

标签: c# wpf dialog event-handling caliburn.micro

在我们的应用程序中,我们使用WPF和Caliburn Micro。我们使用自定义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;
    }
}

在我们的代码中,我们主要使用这个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
}

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

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
}

不幸的是,如果关闭Window,ShowDialog也会返回false(即使ShowDialog返回一个Nullable bool(bool?))。

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

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

但是当我希望它关闭时(例如按下取消/确定按钮时)它也会取消关闭。也许我可以为这个被覆盖的Closing-EventHandler添加一些Property-flag,但也许你们/女孩有其他的建议来完成相同的结果。

2 个答案:

答案 0 :(得分:0)

如果您只是通过扩展Window课程来实现自己的对话Window,则可以满足您的要求。在自定义Window内,您可以处理Closed事件,并在这种情况下将Window.DialogResult属性设置为null。对于正常的OkCancel州,您只需将Click个处理程序附加到Button个,并将Window.DialogResult属性设置为truefalse因此。{/ p>

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的以下页面中找到更多有用的信息:

  

Dialog Boxes Overview
  Window.DialogResult Property

答案 1 :(得分:0)

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

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