前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >07Prism WPF 入门实战 - Dialog

07Prism WPF 入门实战 - Dialog

作者头像
JusterZhu
发布2022-12-07 20:02:31
9280
发布2022-12-07 20:02:31
举报
文章被收录于专栏:JusterZhuJusterZhu

概要

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的参数

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概要
  • 详细内容
  • 应用
    • .Xaml文件内容
      • .cs文件内容
        • 注册dialog
          • ViewModel中使用
            • 运行效果
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档