自定义对话框服务
当原有对话框不能满足需求的时候,可以通过自定义对话框来实现特殊的需求
一.自定义对话框主机服务步骤:
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 主窗口上面显示