自定义对话框服务
当原有对话框不能满足需求的时候,可以通过自定义对话框来实现特殊的需求
一.自定义对话框主机服务步骤:
1.建立一个IDialogHostService 接口类,继承自 IDialogService 对话框服务类。并且自定义基类的服务方法。
public interface IDialogHostService:IDialogService
{Task<IDialogResult> ShowDialog(string name,IDialogParameters parameters,string dialogHostName="Root");
}
2.创建一个 IDialogHostAware 接口类
public interface IDialogHostAware{//Dialoghost 名称string DialogHostName { get; set; }//打开窗口过程中所接收的参数void OnDialogOpend(IDialogParameters parameters);//取消命令DelegateCommand CancelCommand { get; set; }//保存命令DelegateCommand SaveCommand { get; set; }}
2.接着,实现基类自定义主机服务的方法
/// <summary>
/// 自定义对话主机服务
/// </summary>
public class DialogHostService : DialogService, IDialogHostService
{private readonly IContainerExtension _containerExtension;public DialogHostService(IContainerExtension containerExtension) : base(containerExtension){this._containerExtension = containerExtension;}public async Task<IDialogResult> ShowDialog(string name, IDialogParameters parameters, string dialogHostName = "Root"){parameters ??= new DialogParameters();//从容器中取出弹出窗口的实例var content= _containerExtension.Resolve<object>(name);//验证实例有效性if (!(content is FrameworkElement dialogContent))throw new NullReferenceException("A dialog's content must be a FrameworkElement");if (dialogContent is FrameworkElement view && view.DataContext is null && ViewModelLocator.GetAutoWireViewModel(view) is null){ViewModelLocator.SetAutoWireViewModel(view, true);}if (!(dialogContent.DataContext is IDialogHostAware viewModel))throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface");viewModel.DialogHostName = dialogHostName;//打开过程中,所执行的事件DialogOpenedEventHandler eventHandle = (sender, args) =>{if (viewModel is IDialogHostAware aware){aware.OnDialogOpend(parameters);}args.Session.UpdateContent(content);};return (IDialogResult) await DialogHost.Show(dialogContent, viewModel.DialogHostName, eventHandle);}
}
二.把对话框主机服务,进行依赖注册。
containerRegistry.Register<IDialogHostService, DialogHostService>();
三.修改ViewModels 中Dialog 文件夹中待办事项和备忘录弹窗视图继承逻辑
1.修改 AddToDoViewModel后台处理逻辑类继承自IDialogHostAware
public class AddToDoViewModel : IDialogHostAware{public AddToDoViewModel(){CancelCommand = new DelegateCommand(Cancel);SaveCommand = new DelegateCommand(Save);}public string DialogHostName { get; set; }public DelegateCommand CancelCommand { get; set; }public DelegateCommand SaveCommand { get; set; }public void OnDialogOpend(IDialogParameters parameters){}private void Cancel(){if (DialogHost.IsDialogOpen(DialogHostName)) //是否是打开{DialogHost.Close(DialogHostName,new DialogResult(ButtonResult.No)); //关闭}}private void Save(){if (DialogHost.IsDialogOpen(DialogHostName)) //是否是打开{DialogParameters pairs = new DialogParameters(); //定义返回参数DialogHost.Close(DialogHostName, new DialogResult(ButtonResult.OK, pairs));}}}
2.修改 AddMemoViewModel 后台处理逻辑类继承自IDialogHostAware
public class AddMemoViewModel : IDialogHostAware
{public AddMemoViewModel(){CancelCommand = new DelegateCommand(Cancel);SaveCommand = new DelegateCommand(Save);}public string DialogHostName { get; set; }public DelegateCommand CancelCommand { get; set; }public DelegateCommand SaveCommand { get; set; }public void OnDialogOpend(IDialogParameters parameters){}private void Cancel(){if (DialogHost.IsDialogOpen(DialogHostName)) //是否是打开{DialogHost.Close(DialogHostName,new DialogResult(ButtonResult.No)); //关闭} }private void Save(){if (DialogHost.IsDialogOpen(DialogHostName)) //是否是打开{DialogParameters pairs = new DialogParameters(); //定义返回参数DialogHost.Close(DialogHostName,new DialogResult (ButtonResult.OK,pairs)); }}}
3.修改弹窗视图 待办事项和备忘录,给按钮添加命令绑定
4.最后再修改原弹窗注册服务,直接添加进容器中即可。
四. 修改 IndexViewModel 处理逻辑
public class IndexViewModel:BindableBase
{public IndexViewModel(IDialogHostService dialogService){TaskBars=new ObservableCollection<TaskBar>();ToDoDtos = new ObservableCollection<ToDoDto>();MemoDtos = new ObservableCollection<MemoDto>();ExecuteCommand = new DelegateCommand<string>(Execute);CreateTaskBars();CreateTestDate();this.dialogService = dialogService;}public DelegateCommand<string> ExecuteCommand { get; private set; }private ObservableCollection<TaskBar> taskBars;public ObservableCollection<TaskBar> TaskBars{get { return taskBars; }set { taskBars = value; RaisePropertyChanged(); }}private ObservableCollection<ToDoDto> toDoDtos;public ObservableCollection<ToDoDto> ToDoDtos{get { return toDoDtos; }set { toDoDtos = value; RaisePropertyChanged(); }}private ObservableCollection<MemoDto> memoDtos;private readonly IDialogHostService dialogService;public ObservableCollection<MemoDto> MemoDtos{get { return memoDtos; }set { memoDtos = value; RaisePropertyChanged(); }}void CreateTaskBars(){TaskBars.Add(new TaskBar() { Icon="ClockFast",Title="汇总",Content="9",Color="#FF0CA0FF",Target=""});TaskBars.Add(new TaskBar() { Icon = "ClockCheckOutline", Title = "已完成", Content = "9", Color = "#FF1ECA3A", Target = "" });TaskBars.Add(new TaskBar() { Icon = "ChartLineVariant", Title = "完成比例", Content = "9%", Color = "#FF02C6DC", Target = "" });TaskBars.Add(new TaskBar() { Icon = "PlaylistStar", Title = "备忘录", Content = "18", Color = "#FFFFA000", Target = "" });}void CreateTestDate(){for (int i = 0; i < 10; i++){ToDoDtos.Add(new ToDoDto { Title="待办"+i,Content="正在处理中.."});MemoDtos.Add(new MemoDto { Title = "备忘" + i, Content = "我的密码" });}}private void Execute(string obj){switch(obj){case "新增备忘录":dialogService.ShowDialog("AddMemoView",null, "RootDialog");break;case "新增待办事项":dialogService.ShowDialog("AddToDoView",null, "RootDialog");break;}}
}
1.由于主窗口,有一个Identifier 的名称叫 RootDialog
2.所以修改 IndexViewModel 中弹窗逻辑,传过去的名称就叫RootDialog,即表示所有的弹窗,都会在 MainView 主窗口上面显示