棱镜。关闭使用 IDialogService 创建的对话框
Prism. Closing a dialog created with IDialogService
我正在尝试使用 github 问题 1666. A New IDialogService for WPF 中讨论的新 IDialogService。我喜欢这个新功能,但与 InteractionRequest 相比,我找不到一个使用 IDialogService 的解决方案。
有一个按钮,按下打开非模态对话框。如果用户再次按下同一个按钮,而对话框仍然打开,则对话框关闭。这种行为应该如何以正确的方式实施?
MainWindowViewModel
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 => { });
}
}
CustomPopupViewModel
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的名字除外。
您始终可以通过事件聚合器发送事件,如果一次打开多个对话框,您可能必须在对话框参数中传递一些 id 以关闭正确的对话框。
但这感觉真的很笨拙,我更愿意从 Show
/ShowDialog
得到一个 IDisposable
来关闭 Dispose
上的对话框。
public CustomPopupViewModel(IEventAggregator eventAggregator)
{
eventAggregator.GetEvent<CloseDialogEvent>().Subscribe( id => { if (id == _id) CloseMe(); } );
}
public void OnDialogOpened(IDialogParameters parameters)
{
_id = parameters.GetValue<string>("id");
}
_dialogService.Show("CustomPopupView", new DialogParameters("id=12345"), result => { });
_eventAggregator.GetEvent<CloseDialogEvent>().Publish("12345");
我发现使用订阅者模式的 Prism 实现最简单
我使用将在模式中使用并传达的 class:
public class DialogStatus
{
public bool DialogResult { get; set; }
}
在我的示例中,我向您展示了如何使用 Prism 8.0.0.1909 在 WPF 中使用登录对话框来执行此操作
在App.cs
protected override void OnInitialized()
{
var login = Container.Resolve<LoginDialog>();
var result = login.ShowDialog();
if (result.HasValue && result.Value)
{
base.OnInitialized();
}
else
{
Application.Current.Shutdown();
}
}
在 LoginDialog.cs 在我的 Dialogs 文件夹
public partial class LoginDialog : Window
{
public LoginDialog(IEventAggregator eventAggregator)
{
InitializeComponent();
eventAggregator.GetEvent<CloseDialogWindowEvent>().Subscribe(OnCloseWindow);
}
private void OnCloseWindow(DialogStatus obj)
{
base.DialogResult = obj.DialogResult;
}
}
现在在我的代码中的任何地方,在视图的 ViewModel 或自定义控件的视图模型中,我唯一需要做的就是在构造函数中传递 IEventAggregator 并将其保存在字段中。
private readonly IEventAggregator _eventAggregator;
public LoginControlViewModel(IAuthenticationService authenticationService
, IConnectFileImporterService connectFileImporterService
, IDialogService dialogService
, IEventAggregator eventAggregator)
{
_eventAggregator= eventAggregator;
// the other code
}
我现在可以关闭我的对话框,在此示例中 return true 可以从任何地方通过调用
落入我的 App.cs 中的 OnInitalize
_eventAggregator.GetEvent<CloseDialogWindowEvent>().Publish(new CloseDialogWindowEvent() { DialogResult = true });
或
_eventAggregator.GetEvent<CloseDialogWindowEvent>().Publish(new CloseDialogWindowEvent() { DialogResult = false});
我正在尝试使用 github 问题 1666. A New IDialogService for WPF 中讨论的新 IDialogService。我喜欢这个新功能,但与 InteractionRequest 相比,我找不到一个使用 IDialogService 的解决方案。
有一个按钮,按下打开非模态对话框。如果用户再次按下同一个按钮,而对话框仍然打开,则对话框关闭。这种行为应该如何以正确的方式实施?
MainWindowViewModel
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 => { });
}
}
CustomPopupViewModel
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的名字除外。
您始终可以通过事件聚合器发送事件,如果一次打开多个对话框,您可能必须在对话框参数中传递一些 id 以关闭正确的对话框。
但这感觉真的很笨拙,我更愿意从 Show
/ShowDialog
得到一个 IDisposable
来关闭 Dispose
上的对话框。
public CustomPopupViewModel(IEventAggregator eventAggregator)
{
eventAggregator.GetEvent<CloseDialogEvent>().Subscribe( id => { if (id == _id) CloseMe(); } );
}
public void OnDialogOpened(IDialogParameters parameters)
{
_id = parameters.GetValue<string>("id");
}
_dialogService.Show("CustomPopupView", new DialogParameters("id=12345"), result => { });
_eventAggregator.GetEvent<CloseDialogEvent>().Publish("12345");
我发现使用订阅者模式的 Prism 实现最简单 我使用将在模式中使用并传达的 class:
public class DialogStatus
{
public bool DialogResult { get; set; }
}
在我的示例中,我向您展示了如何使用 Prism 8.0.0.1909 在 WPF 中使用登录对话框来执行此操作
在App.cs
protected override void OnInitialized()
{
var login = Container.Resolve<LoginDialog>();
var result = login.ShowDialog();
if (result.HasValue && result.Value)
{
base.OnInitialized();
}
else
{
Application.Current.Shutdown();
}
}
在 LoginDialog.cs 在我的 Dialogs 文件夹
public partial class LoginDialog : Window
{
public LoginDialog(IEventAggregator eventAggregator)
{
InitializeComponent();
eventAggregator.GetEvent<CloseDialogWindowEvent>().Subscribe(OnCloseWindow);
}
private void OnCloseWindow(DialogStatus obj)
{
base.DialogResult = obj.DialogResult;
}
}
现在在我的代码中的任何地方,在视图的 ViewModel 或自定义控件的视图模型中,我唯一需要做的就是在构造函数中传递 IEventAggregator 并将其保存在字段中。
private readonly IEventAggregator _eventAggregator;
public LoginControlViewModel(IAuthenticationService authenticationService
, IConnectFileImporterService connectFileImporterService
, IDialogService dialogService
, IEventAggregator eventAggregator)
{
_eventAggregator= eventAggregator;
// the other code
}
我现在可以关闭我的对话框,在此示例中 return true 可以从任何地方通过调用
落入我的 App.cs 中的 OnInitalize_eventAggregator.GetEvent<CloseDialogWindowEvent>().Publish(new CloseDialogWindowEvent() { DialogResult = true });
或
_eventAggregator.GetEvent<CloseDialogWindowEvent>().Publish(new CloseDialogWindowEvent() { DialogResult = false});