在我们的应用程序中,我们使用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,但也许你们/女孩有其他的建议来完成相同的结果。
答案 0 :(得分:0)
如果您只是通过扩展Window
课程来实现自己的对话Window
,则可以满足您的要求。在自定义Window
内,您可以处理Closed
事件,并在这种情况下将Window.DialogResult
属性设置为null
。对于正常的Ok
和Cancel
州,您只需将Click
个处理程序附加到Button
个,并将Window.DialogResult
属性设置为true
, false
因此。{/ 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的以下页面中找到更多有用的信息:
答案 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)
。