我正在尝试使用一个新的IDialogService,这在github的1666. A New IDialogService for WPF期中讨论过。我喜欢这个新特性,但是我找不到一个解决方案来解决使用IDialogService与InteractionRequest相比的问题。
有一个按钮,按下它会打开非模态对话框。如果用户再次按下同一个按钮,而对话框仍然打开,对话框关闭。应该如何以正确的方式实现此行为?
主窗口视图模型
public class MainWindowViewModel : BindableBase
{
private readonly IDialogService _dialogService;
public DelegateCommand CustomPopupCommand { get; }
public MainWindowViewModel(IDialogService dialogService)
{
_dialogService = dialogService;
CustomPopupCommand = new DelegateCommand(OpenClosePopup);
}
private void OpenClosePopup()
{
// It looks like some additional logic should be implemented here.
// How to save previously opened IDialogAware instance and close it if needed?
_dialogService.Show("CustomPopupView", new DialogParameters("Title=Good Title"), result => { });
}
}
自定义弹出视图模型
public class CustomPopupViewModel : BindableBase, IDialogAware
{
private string _title;
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
public DelegateCommand<object> CloseCommand { get; }
public CustomPopupViewModel()
{
CloseCommand = new DelegateCommand<object>(CloseDialog);
}
public event Action<IDialogResult> RequestClose;
public void OnDialogOpened(IDialogParameters parameters)
{
Title = parameters.GetValue<string>(nameof(Title));
}
public void OnDialogClosed()
{
}
public bool CanCloseDialog()
{
return true;
}
public void RaiseRequestClose(IDialogResult dialogResult)
{
RequestClose?.Invoke(dialogResult);
}
private void CloseDialog(object button)
{
RaiseRequestClose(
new DialogResult(button is ButtonResult buttonResult ? buttonResult : ButtonResult.Cancel));
}
}
我不知道如何以正确的方式实现它,因为IDialogService.Show()方法与ViewModel和View完全分离,当然View的名称除外。
3条答案
按热度按时间jq6vz3qz1#
你总是可以通过事件聚合器发送一个事件,如果一次打开多个对话框,你可能需要在对话框参数中传递一些id来关闭正确的对话框。
但这感觉真的很笨重,我更喜欢从
Show
/ShowDialog
获得一个IDisposable
,关闭Dispose
上的对话框。hec6srdp2#
我发现使用订户模式的Prism实现是最简单的,我使用了一个将在模式中使用并进行通信的类:
在我的示例中,我将向您展示如何使用Prism 8.0.0.1909在WPF中使用登录对话框来执行此操作
在应用程序cs中
在我的对话框文件夹的LoginDialog.cs中
现在,在代码中的任何地方,在视图的ViewModel中,在自定义控件的视图模型中,我唯一需要做的事情就是在构造函数中传递IEventAggregator并将其保存在字段中。
现在,我可以关闭对话框,并在此示例中,通过调用以下命令,从任何位置将falls返回到App.cs中的OnInitalize
或
798qvoo83#
如果我没理解错的话,你想用编程的方式来关闭日志窗口,而不是点击窗口的关闭按钮,对吗?如果是这样的话,也许我可以为你提供一个解决方案。虽然这个方法不是很优雅,但它非常简单。
我的项目使用mahapps风格,我想使用metrowindow作为dailoghost窗口。根据prism文档,我注册了dailoghost窗口和用户控件,如下所示:
UserEidt是一个用户控件,我在UserEidt中放置了一个确认按钮和一个取消按钮,并且这两个按钮都绑定了UserEditViewModel中的DelegateCommand。问题是,如何通过单击取消按钮来关闭日志窗口?
下面是我的解决方案,首先定义一个IDailogViewModel接口:
然后UserEditViewModel实现这个接口:
实际上,当对话框窗口弹出时,UserEdit将是dialogWindow的内容,所以在dialogWindow的已加载事件处理程序中,我可以使用Window.Content来获取UserEdit对象,代码如下:
现在,单击取消按钮后,对话框窗口将关闭。