Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.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# 获取窗口显示对话框取消和关闭之间的差异_C#_Wpf_Dialog_Event Handling_Caliburn.micro - Fatal编程技术网

C# 获取窗口显示对话框取消和关闭之间的差异

C# 获取窗口显示对话框取消和关闭之间的差异,c#,wpf,dialog,event-handling,caliburn.micro,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(mo

在我们的应用程序中,我们使用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
}
在我最近的一个方法中,我希望(在半伪代码中)执行以下操作:

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

因此,到目前为止,我所做的只是通过创建一个新的
窗口行为
来完全删除关闭按钮,并将其添加到
if(isDialog)
中的
OurWindowManager
类中:

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

所以,我的问题是:如何在上面提到的
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添加某种属性标志,但也许你们有其他建议来实现相同的结果。

如果您只需通过扩展
窗口
类来实现自己的对话框
窗口
,就可以满足您的要求。在自定义的
窗口中
,您可以处理
关闭
事件,并将
窗口的DialogResult
属性设置为
null
。对于正常的
Ok
Cancel
状态,您只需将
单击
处理程序附加到这些
按钮
上,并相应地设置
窗口。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;
}
然后,您可以检查
窗口的关闭状态,如下所示:

if (CustomDialogWindow.DialogResult == null) DoSomethingUponDialogWindowClose();
您可以在MSDN的以下页面中找到更多有用的信息:


根据的建议,我在ConfirmDialogViewModel中添加了ClosedBy属性:

(之前):

(之后):

我现在这样使用它:

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到<代码> OutWindows管理器< /> >在代码> >(I对话)< /C> > /P>我会考虑这样一个事实:如果单击“取消”和“关闭”窗口做不同的事情,用户可能有点不直观。Win窗体中有<代码> CuteleSeason < /Case>作为参数传递到窗体。在wpf中,您可以在对话框中实现它(作为属性)。@Sinatr据我所知,wpf中确实没有
CloseReason
。我自己从来没有使用过表单,但当我在谷歌上搜索如何抓住取消和关闭之间的区别时,我确实发现了一些东西。生成枚举,生成属性
ClosedBy
,如果按下
Cancel
按钮,则设置
ClosedBy=Cancel
并关闭窗口(对于
Ok
按钮-
ClosedBy=Ok
),默认值可以是
Unknown
(不知道如何区分
Alt-F4
和Windows关闭请求,但也许你不需要它)。@BenRobinson也许你是对的。。现在,它询问用户是否希望在继续之前保存数据(是、否和关闭不应执行任何操作/取消操作)。是否可以使用三个按钮而不是两个按钮在ViewModel上调用ShowDialog(因此我的对话框行为与在
OurWindowManager
中添加的相同)?
if (CustomDialogWindow.DialogResult == null) DoSomethingUponDialogWindowClose();
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
}