07Prism WPF 入门实战 - Dialog

2022-12-07 20:02:31 浏览数 (1)

概要

Prism中的dialog(对话框)实际上是我们应用程序经常用到得一个功能,类如:Show、Show Dialog。可以弹出一个我们指定得窗口,仅此而已那么在Prism当中,Dialog指的什么?Prism提供了一组对话服务,封装了常用的对话框组件的功能,例如:IDialogAware(注册对话及使用对话)打开对话框传递参数/关闭对话框返回参数回调通知对话结果。

  • 应用场景:处理一些公共业务,例如正在编辑文章内容这时候如果要关闭程序或者打开其他页面需要提示。
  • 在Prism体系中的应用分为,1.自定义dialog窗体 2.将写好的dialog注入到App.xaml.csI中的ContainerRegistry里。3.业务ViewModel的构造函数中获取引用进行调用

详细内容

我们先来看看它源码中的定义:

代码语言:javascript复制
namespace Prism.Services.Dialogs
{
    //
    // 摘要:
    //     Interface that provides dialog functions and events to ViewModels.
    public interface IDialogAware
    {
        //
        // 摘要:
        //     The title of the dialog that will show in the window title bar.
        string Title
        {
            get;
        }

        //
        // 摘要:
        //     Instructs the Prism.Services.Dialogs.IDialogWindow to close the dialog.
        event Action<IDialogResult> RequestClose;

        //
        // 摘要:
        //     Determines if the dialog can be closed.
        //
        // 返回结果:
        //     If true the dialog can be closed. If false the dialog will not close.
        bool CanCloseDialog();

        //
        // 摘要:
        //     Called when the dialog is closed.
        void OnDialogClosed();

        //
        // 摘要:
        //     Called when the dialog is opened.
        //
        // 参数:
        //   parameters:
        //     The parameters passed to the dialog.
        void OnDialogOpened(IDialogParameters parameters);
    }
}

解读一下IDialogAware接口中内容各有什么作用。

  • (1)string Title{get;} //将显示在窗口标题栏中的对话框的标题。
  • (2)event Action<IDialogResult> RequestClose;//指示 Prism.Services.Dialogs.IDialogWindow 关闭对话框。
  • (3)bool CanCloseDialog();//确定是否可以关闭对话框。
  • (4)void OnDialogClosed();//关闭对话框时触发
  • (5)void OnDialogOpened(IDialogParameters parameters);//打开对话框时触发, parameters:传递给对话框的参数。

应用

首先创建好Dialog的窗体的.xaml和窗体处理逻辑的.cs文件,尽量创建在“公共库”里。

.Xaml文件内容

代码语言:javascript复制
<UserControl x:Class="Wemail.Controls.Views.MessageDialogView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             TextElement.Foreground="{DynamicResource MaterialDesignBody}"
             Background="{DynamicResource MaterialDesignPaper}"
             xmlns:local="clr-namespace:Wemail.Controls.Views"
             mc:Ignorable="d" 
             Height="450" Width="500">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="40"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="1" Background="Transparent" Foreground="White" Text="{Binding MessageContent,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
        <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Width="100" Height="30" Margin="5" Content="确定" Command="{Binding GetMessageCommand}"></Button>
            <Button Width="100" Height="30" Margin="5" Content="取消" Command="{Binding CancelMessageCommand}"></Button>
        </StackPanel>
    </Grid>
</UserControl>

.cs文件内容

代码语言:javascript复制
namespace Wemail.Controls.CustomContorls
{
    public class MessageDialogControl : BindableBase , IDialogAware
    {
        private DelegateCommand _getMessageCommand;
        private DelegateCommand _cancelMessageCommand;
        private string _messageContent;

        public string MessageContent 
        { 
            get => _messageContent;
            set 
            {
                _messageContent = value;
                SetProperty(ref _messageContent, value);
            }
        }

        /// <summary>
        /// 确定按钮
        /// </summary>
        public DelegateCommand GetMessageCommand 
        {
            get => _getMessageCommand = new DelegateCommand(() => 
            {
                var parameter = new DialogParameters();
                parameter.Add("MessageContent", MessageContent);
                RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameter));
            });
        }

        /// <summary>
        /// 窗体关闭按钮
        /// </summary>
        public DelegateCommand CancelMessageCommand 
        { 
            get => _cancelMessageCommand = new DelegateCommand(() => 
            {
                RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
            });
        }

        public string Title => "Message";
        public event Action<IDialogResult> RequestClose;

        /// <summary>
        /// 允许用户手动关闭当前窗口
        /// </summary>
        /// <returns></returns>
        public bool CanCloseDialog()
        {
            //根据业务需要来控制是否允许手动关闭
            return true;
        }

        /// <summary>
        /// 关闭dialog的操作
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        public void OnDialogClosed()
        {
            //当关闭dialog的时候会触发的回调,一般用来打日志或者用于用户行为记录等场景
        }

        /// <summary>
        /// dialog接收参数传递
        /// </summary>
        /// <param name="parameters"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void OnDialogOpened(IDialogParameters parameters)
        {
            //接受viewmodel打开dialog时传递的参数内容
            var parameterContent = parameters.GetValue<string>("juster");
        }
    }
}

注册dialog

App.xaml.cs文件使用如下:

代码语言:javascript复制
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
        var factory = new NLog.Extensions.Logging.NLogLoggerFactory();
        _logger = factory.CreateLogger("NLog");
        //注入到Prism DI容器中
        containerRegistry.RegisterInstance(_logger);

        //注册Dialog窗体
        containerRegistry.RegisterDialog<MessageDialogView, MessageDialogControl>();
    }

ViewModel中使用

代码语言:javascript复制
namespace Wemail.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Application";

        //Region管理对象
        private IRegionManager _regionManager;
        private IModuleCatalog _moduleCatalog;
        private IModuleInfo _moduleInfo;
        private ILogger _logger;
        private IDialogService _dialogService;
        private ObservableCollection<IModuleInfo> _modules;
        private DelegateCommand _loadModulesCommand;
        private DelegateCommand _showDialogCommand;
        
        public IView View { get; set; }

        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public ObservableCollection<IModuleInfo> Modules
        {
            get => _modules ?? (_modules = new ObservableCollection<IModuleInfo>());
        }

        public DelegateCommand LoadModulesCommand { get => _loadModulesCommand = new DelegateCommand(InitModules); }

        public IModuleInfo ModuleInfo 
        { 
            get 
            {
                return _moduleInfo; 
            }

            set 
            {
                _moduleInfo = value;
                Navigate(value);
            }
        }

        public DelegateCommand ShowDialogCommand { get => _showDialogCommand = new DelegateCommand(ShowDialogAction); }

        /// <summary>
        /// 调用dialog
        /// </summary>
        private void ShowDialogAction()
        {
            //需要传递给对话框处理的内容参数
            DialogParameters dialogParameters = new DialogParameters();
            dialogParameters.Add("juster","nihao");
            //打开dialog的时候传递
            _dialogService.ShowDialog("MessageDialogView", dialogParameters, (r) => 
            {
                var result = r.Result;
                if (result == ButtonResult.OK) 
                {
                    var parameter = r.Parameters.GetValue<string>("MessageContent");
                }
            });
        }

        public MainWindowViewModel(IRegionManager regionManager, IModuleCatalog moduleCatalog,ILogger logger,IDialogService dialogService)
        {
            _dialogService = dialogService;
            _logger = logger;
            _regionManager = regionManager;
            _moduleCatalog = moduleCatalog;
        }

        public void InitModules() 
        {
            var dirModuleCatalog = _moduleCatalog as DirectoryModuleCatalog;
            Modules.AddRange(dirModuleCatalog.Modules);
        }

        private void Navigate(IModuleInfo info) 
        {
            var paramete = new NavigationParameters();
            //任意定义key,value。导航到的视图按照约定key获取value即可。
            paramete.Add($"{ info.ModuleName }", DateTime.Now.ToString());
            _regionManager.RequestNavigate("ContentRegion", $"{ info.ModuleName }View", paramete);
        }
    }
}

运行效果

关闭对话框之后viewmodel接收到的参数

窗体被打开时接收到viewmodel的参数

0 人点赞