实现自己的对话框服务
参照prism源码IDialogService实现自己的对话框服务接口
public interface IAppDialogService
{
void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback);
void CloseDialog(string dialogHostName);
}
因为prism自带创建的对话框window很丑陋,且IDialogAware总带有Title属性,实际并不需要用到,故自定义个IAppDialogAware接口
public interface IAppDialogAware
{
bool CanCloseDialog();
/// <summary>
/// Called when the dialog is closed.
/// </summary>
void OnDialogClosed();
/// <summary>
/// Called when the dialog is opened.
/// </summary>
/// <param name="parameters">The parameters passed to the dialog.</param>
void OnDialogOpened(IDialogParameters parameters);
/// <summary>
/// Instructs the <see cref="IDialogWindow"/> to close the dialog.
/// </summary>
event Action<IDialogResult> RequestClose;
}
实现自己的对话框服务,集成materialdesign
public class AppDialogService:IAppDialogService
{
private readonly IContainerExtension _containerExtension;
public AppDialogService(IContainerExtension containerExtension)
{
_containerExtension = containerExtension;
}
public void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback)
{
parameters ??= new DialogParameters();
var content = _containerExtension.Resolve<object>(name);
var dialogContent = ParseToFrameworkElement(content);
var viewModel = BindViewModel(dialogContent);
viewModel.RequestClose -= callback;
viewModel.RequestClose += callback;
viewModel.OnDialogOpened(parameters);
RegionManager.SetRegionManager(dialogContent, _containerExtension.Resolve<IRegionManager>());
RegionManager.UpdateRegions();
DialogHost.Show(content,"Root", null, ExtendedClosingEventHandler, closedEventHandler: ExtendedClosedEventHandler);
}
private void ExtendedClosingEventHandler(object sender, DialogClosingEventArgs eventArgs)
{
var content = eventArgs.Session?.Content;
var dialogContent = ParseToFrameworkElement(content);
var viewModel = BindViewModel(dialogContent);
if (!viewModel.CanCloseDialog())
eventArgs.Cancel();
}
private void ExtendedClosedEventHandler(object sender, DialogClosedEventArgs eventArgs)
{
var content = eventArgs.Session?.Content;
var obj = ParseToFrameworkElement(content);
var viewModel = BindViewModel(obj);
viewModel.OnDialogClosed();
RegionManager.SetRegionManager(obj, null);
RegionManager.UpdateRegions();
}
public void CloseDialog(string dialogHostName)
{
DialogHost.Close(dialogHostName);
}
#region Private Helpers
private FrameworkElement ParseToFrameworkElement(object content)
{
if (!(content is FrameworkElement obj))
throw new NullReferenceException("A dialog's content must be a FrameworkElement");
return obj;
}
private IAppDialogAware BindViewModel(FrameworkElement obj)
{
if (obj.DataContext is null && ViewModelLocator.GetAutoWireViewModel(obj) is null)
{
ViewModelLocator.SetAutoWireViewModel(obj, true);
}
if (!(obj.DataContext is IAppDialogAware viewModel))
throw new NullReferenceException("A dialog's ViewModel must implement the IAppDialogAware interface");
return viewModel;
}
#endregion
}
登录调用接口显示对话框,且传递参数
public class LoginViewModel:BindableBase
{
private readonly IAppDialogService _dialogService;
private string? _title;
public string? Title
{
get => _title;
set => SetProperty(ref _title, value);
}
public DelegateCommand LoginCommand { get; set; }
public LoginViewModel(IAppDialogService dialogService)
{
_dialogService = dialogService;
LoginCommand = new DelegateCommand(Login);
Title = "this is a login view!";
}
private void Login()
{
DialogParameters parameters = new DialogParameters();
parameters.Add("title", _title);
_dialogService.ShowDialog("SettingDialog", parameters, (o) =>
{
if (o.Result == ButtonResult.OK)
{
Title = "登录成功";
}
});
}
}
在对话框vm中OnDialogOpened接收传递参数,OnDialogClosed使用RequestClose回调结果信息和返回的参数
public class SettingDialogViewModel : BindableBase, IAppDialogAware
{
private readonly IRegionManager _regionManager;
public event Action<IDialogResult> RequestClose;
public SettingDialogViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
}
public bool CanCloseDialog()
{
return true;
}
public void OnDialogClosed()
{
DialogParameters parameters = new DialogParameters();
parameters.Add("LoginResult", true);
RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
}
public void OnDialogOpened(IDialogParameters parameters)
{
}
}