C# 获取窗口显示对话框取消和关闭之间的差异
在我们的应用程序中,我们使用WPF和Caliburn Micro。我们使用自定义WindowManager: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
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
}