获取窗口显示对话框取消和关闭之间的区别
本文关键字:之间 区别 窗口 显示 对话框 取消 获取 | 更新日期: 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
。对于正常的Ok
和Cancel
状态,只需将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;
。