【WPF】Prism P2

 

一、弹窗设置

Step1 在模块A创建弹窗A和弹窗B,注意,还是要使用【用户控件】

<UserControl x:Class="ModuleA.Views.DialogA"
             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" 
             xmlns:local="clr-namespace:ModuleA.Views"
             mc:Ignorable="d" 
             Height="450" Width="800">
    <Grid Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>

        <TextBlock Text="温馨提示" />
        <TextBlock VerticalAlignment="Center" Text="这是DialogA" FontSize="30" Grid.Row="1" />

        <StackPanel Orientation="Horizontal" Grid.Row="2">
            <Button Content="取消" Margin="5" FontSize="15" Command="{ Binding CancelCommand  }" />
            <Button Content="确定" Margin="5" FontSize="15" Command="{ Binding ConfirmCommand }" />
        </StackPanel>
    </Grid>
</UserControl>

 

目录位置:

  

Step2 创建弹窗A和B对应的视图类,并且该类需要实现IDialogAware接口(仅实例A)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImTools;
using Prism.Commands;
using Prism.Services.Dialogs;

namespace ModuleA.ViewModels
{
    /* 弹窗视图类需要实现 Prism.Services.Dialogs.IDialogAware接口 */
    internal class DialogAViewModel : IDialogAware
    {
        public string Title { get; set; }

        public event Action<IDialogResult> RequestClose;

        /* 设定弹窗的确认和取消命令 */
        public DelegateCommand CancelCommand { get; set; }
        public DelegateCommand ConfirmCommand { get; set; }


        public DialogAViewModel() 
        {
            /* 命令初始化 */
            CancelCommand = new DelegateCommand(cancel);
            ConfirmCommand = new DelegateCommand(confirm);
        }

        /* 设置这个弹窗允许关闭 */
        public bool CanCloseDialog()
        {
            return true;
        }


        /* 当弹窗关闭时回调方法 */
        public void OnDialogClosed()
        {
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Value", "Message From DialogA");
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, keyValuePairs));
        }

        /* 当弹窗打开时回调方法,接受一个参数对象 */
        public void OnDialogOpened(IDialogParameters parameters)
        {
            if (parameters.ContainsKey("Title"))
            {
                Title = parameters.GetValue<string>("Title");
            }
        }

        /* 确认方法 */
        private void confirm()
        {
            OnDialogClosed();
        }

        /* 取消方法 */
        private void cancel()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.No));
        }
    }
}

  

 回到模块AProfile类注册弹窗A和B:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ModuleA.ViewModels;
using ModuleA.Views;
using Prism.Ioc;
using Prism.Modularity;

namespace ModuleA
{
    public class ModuleAProfile : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<ViewD, ViewDViewModel>();
            containerRegistry.RegisterDialog<DialogA, DialogAViewModel>();
            containerRegistry.RegisterDialog<DialogB, DialogBViewModel>();
        }
    }
}

  

 MainViewModel类追加弹窗打开方法:

当回调触发时可以接受弹窗信息发送的参数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;

namespace WPF_Prism.ViewModels
{
    internal class MainViewModel : BindableBase
    {

        public DelegateCommand<string> OpenCommand { private set; get; }
        public DelegateCommand BackCommand { private set; get; }

        public DelegateCommand<string> OpenDialogCommand { private set; get; }

        private readonly IRegionManager regionManager;
        private readonly IDialogService dialogService;
        private IRegionNavigationJournal journal;


        /* 初始化时通过构造器注入区域管理器对象 */
        public MainViewModel(IRegionManager regionManager, IDialogService dialogService)
        {
            /* 命令逻辑初始化 */
            OpenCommand = new DelegateCommand<string>(Open);
            BackCommand = new DelegateCommand(Back);
            OpenDialogCommand = new DelegateCommand<string> (OpenDialog);

            /* 初始化Prism资源 */
            this.regionManager = regionManager;
            this.dialogService = dialogService;
        }

        private void Open(string obj)
        {
            /* 可以向路由传递参数 */
            NavigationParameters keys = new NavigationParameters();
            keys.Add("Title", "nav-para");
            /* 通过区域管理器对象,指定区域名获取该区域对象,并导航到目标视图控件对象上 */
            regionManager.Regions["ContentRegion"].RequestNavigate(obj, navigationCallback =>
            {
                if (journal == null && (bool)navigationCallback.Result)
                    journal = navigationCallback.Context.NavigationService.Journal;
            }, keys);
        }

        private void Back()
        {
            if (journal != null && journal.CanGoBack)
            {
                journal.GoBack();
            }
        }

        /* 弹窗打开方法 */
        private void OpenDialog(string obj)
        {
            /* 调用弹窗展示方法之前可以传递参数信息 */
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Title", obj);
            /* 在该弹窗关闭之后可以回调处理逻辑 */
            dialogService.ShowDialog(obj, keyValuePairs, callback =>
            {
                /* 当为确认时再处理逻辑 */
                if (callback.Result == ButtonResult.OK)
                {
                    string result = callback.Parameters.GetValue<string>("Value");
                    Console.WriteLine(result);
                }
            });
        }
    }
}

  

主窗口xaml追加弹窗按钮支持:

<Window x:Class="WPF_Prism.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_Prism"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Button Margin="5" Command="{ Binding OpenCommand }" CommandParameter="ViewA">ViewA</Button>
            <Button Margin="5" Command="{ Binding OpenCommand }" CommandParameter="ViewB">ViewB</Button>
            <Button Margin="5" Command="{ Binding OpenCommand }" CommandParameter="ViewC">ViewC</Button>
            <Button Margin="5" Command="{ Binding OpenCommand }" CommandParameter="ViewD">ViewD</Button>
            <Button Margin="5" Command="{ Binding OpenCommand }" CommandParameter="ViewE">ViewE</Button>
            <Button Margin="5" Command="{ Binding BackCommand }">上一页</Button>
        </StackPanel>

        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Margin="5" Command="{ Binding OpenDialogCommand }" CommandParameter="DialogA">DialogA</Button>
            <Button Margin="5" Command="{ Binding OpenDialogCommand }" CommandParameter="DialogB">DialogB</Button>
        </StackPanel>

        <ContentControl Grid.Row="2" prism:RegionManager.RegionName="ContentRegion" />
    </Grid>
</Window>

  

执行预览:

 

关闭时参数接收的Debug调试 

 

二、事件订阅与发布

在模块A中新建event目录,并添加MessageEvent类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DryIoc.Messages;
using Prism.Events;

namespace ModuleA.Event
{
    /* 定义一般string的消息事件类 */
    public class MessageEvent : PubSubEvent<string>
    {

    }

    /* 定义业务数据实体的消息事件类 */
    public class BusEvent : PubSubEvent<BusData>
    {

    }

    public class BusData
    {
        private int _id;
        private string _code;
        private string _message;

        public int Id { get { return _id; } set { _id = Id; } }
        public string Code { get { return _code; } set { _code = Code; } }
        public string Message { get { return _message; } set { _message = Message; } }
    }
}

  

在弹窗A的类的构造器参数中追加事件聚合器接口:

聚合器根据泛型获取对应的事件对象,并调用订阅回调方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ModuleA.Event;
using Prism.Events;

namespace ModuleA.Views
{
    /// <summary>
    /// DialogA.xaml 的交互逻辑
    /// </summary>
    public partial class DialogA : UserControl
    {
        public DialogA(IEventAggregator eventAggregator)
        {
            InitializeComponent();

            eventAggregator.GetEvent<MessageEvent>().Subscribe(arg =>
            {
                MessageBox.Show($"接收到消息:{arg}");
            });
        }
    }
}

  

弹窗A的视图类,在初始化时发布消息:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImTools;
using ModuleA.Event;
using Prism.Commands;
using Prism.Events;
using Prism.Services.Dialogs;

namespace ModuleA.ViewModels
{
    /* 弹窗视图类需要实现 Prism.Services.Dialogs.IDialogAware接口 */
    internal class DialogAViewModel : IDialogAware
    {
        public string Title { get; set; }

        public event Action<IDialogResult> RequestClose;

        /* 设定弹窗的确认和取消命令 */
        public DelegateCommand CancelCommand { get; set; }
        public DelegateCommand ConfirmCommand { get; set; }

        public DialogAViewModel(IEventAggregator eventAggregator) 
        {
            /* 命令初始化 */
            CancelCommand = new DelegateCommand(cancel);
            ConfirmCommand = new DelegateCommand(confirm);

            eventAggregator.GetEvent<MessageEvent>().Publish("Hello");
        }

        /* 设置这个弹窗允许关闭 */
        public bool CanCloseDialog()
        {
            return true;
        }


        /* 当弹窗关闭时回调方法 */
        public void OnDialogClosed()
        {
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("Value", "Message From DialogA");
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, keyValuePairs));
        }

        /* 当弹窗打开时回调方法,接受一个参数对象 */
        public void OnDialogOpened(IDialogParameters parameters)
        {
            if (parameters.ContainsKey("Title"))
            {
                Title = parameters.GetValue<string>("Title");
            }
        }

        /* 确认方法 */
        private void confirm()
        {
            OnDialogClosed();
        }

        /* 取消方法 */
        private void cancel()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.No));
        }
    }
}

 

执行效果:

先触发消息订阅回调,之后再打开弹窗

 

三、MaterialDesign UI库 

地址:

https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit

发现直接打开项目无法运行:

错误代码是:NETSDK1141

定位到项目的global.json文件

 

打开发现要求dotnet版本是8.0.100

 

但是我在vs的设置里面查看了已经安装的dotnet环境库

 

 可以发现已经安装了8.0的环境

 

然后查看本地DotNet环境时发现使用的版本是9.0.100

命令: dotnet --info

 

所以猜想是因为global.json的版本和本地环境不一致导致,将global.json改为9.0.100版本

 

保存后项目启动正常...

 

可以打包发布出来,里面有组件的演示案例:

 

 

四、MD UI库引入到项目

1、NUGET包管理找到 MD主题资源并下载:

搜素关键字:MaterialDesignThemes

 

2、在App.xaml中,追加关于MD的资源引用

注意这里不要使用MD官方的,需要改用视频地址里的资源引用方式

<prism:PrismApplication x:Class="NoteApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:NoteApp"
             xmlns:prism="http://prismlibrary.com/"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="DeepPurple" SecondaryColor="Lime" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</prism:PrismApplication>

  

3、在主窗口编写一个按钮,测试样式是否有效

<Window x:Class="NoteApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NoteApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Content="hello" Height="50" />
    </Grid>
</Window>

 

启动后预览展示:

 

posted @ 2024-11-28 11:00  emdzz  阅读(8)  评论(0编辑  收藏  举报