首页 > 其他分享 >wpf + MaterialDesign + Prism8 实现导航功能

wpf + MaterialDesign + Prism8 实现导航功能

时间:2023-12-26 14:34:28浏览次数:38  
标签:System private MaterialDesign WindowState Prism using wpf Prism8 public

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

实现的效果:

wpf + MaterialDesign + Prism8 实现导航功能_xml

 1、初始化Prism 

1.1、项目引入如下包

wpf + MaterialDesign + Prism8 实现导航功能_App_02

 1.2、按照Prism规则,项目中创建如下文件夹

wpf + MaterialDesign + Prism8 实现导航功能_App_03

 Prism 规则:必须将窗体放入 Views文件夹中,窗体名称必须以View结尾,必须将数据上下文放入ViewModels文件夹中,上下文类必须以Model结尾

另外两个文件夹分为存放用户控件 及 用户控件使用的数据类

新建窗体MainView 和 MainViewModel、新建用户控件IndexView 和 IndexViewModel、新建用户控件UserView 和 UserViewModel (其实用户控件及上下文类无需遵守Prism规则)

1.3、初始化App.xaml 及 App.cs 

App.cs

using Prism.DryIoc;
using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using WpfApp.UserControls;
using WpfApp.ViewModels;
using WpfApp.Views;

namespace WpfApp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainView>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>();
            containerRegistry.RegisterForNavigation<UserView, UserViewModel>();
        }
    }
}

View Code

App.Xaml

<Prism:PrismApplication x:Class="WpfApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Prism="http://prismlibrary.com/"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:local="clr-namespace:WpfApp" >
    <Application.Resources>
         
    </Application.Resources>
</Prism:PrismApplication>

View Code

App.cs 中重新了二个方法,第一个方法为设定启动窗口,第二个方法为注册导航(两个用户控件为填充内容)

App.xaml 中引入 Prism 命名空间,及改造根节点

2、App.xaml 引入MaterialDesign

 MaterialDesign 的GitHub地址为: https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit 

按照文档引入MaterialDesign,App.xaml 变更为:

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

            <!--自定义样式 样式名:MyListBoxItemStyle,样式挂载:ListBoxItem-->
            <Style x:Key="MyListBoxItemStyle" TargetType="ListBoxItem">
                <!--自定义高度-->
                <Setter Property="MinHeight"
           Value="48" />
                <Setter Property="Template">
                    <Setter.Value>
                        <!--影响属性 ListBoxItem-->
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Grid>
                                <Border x:Name="borderHeader" />
                                <Border x:Name="border" />
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                     VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
                            </Grid>

                            <!--触发器-->
                            <ControlTemplate.Triggers>
                                <!--ListBoxItem点击时触发-->
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="BorderThickness"
                               TargetName="borderHeader"  Value="4,0,0,0"/>
                                    <Setter Property="BorderBrush"
                               TargetName="borderHeader"
                               Value="{DynamicResource PrimaryHueLightBrush}" />
                                    <Setter TargetName="border"
                               Property="Background"
                               Value="{DynamicResource PrimaryHueLightBrush}" />
                                    <Setter TargetName="border"
                               Property="Opacity"
                               Value="0.4" />
                                </Trigger>
                                <!--鼠标悬停触发器触发器-->

                                <Trigger Property="IsMouseOver" Value="True">

                                    <Setter TargetName="border"
                               Property="Background"
                               Value="{DynamicResource PrimaryHueLightBrush}" />

                                    <Setter TargetName="border"
                               Property="Opacity"
                               Value="0.1" />

                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

        </ResourceDictionary>
    </Application.Resources>
</Prism:PrismApplication>

View Code

2.1、检测是否成功引入 MaterialDesign 

在 MainView 中添加一个按钮

<Grid>
        <Button  Content="检测是否成功引入" FontSize="30" Height="80" Width="280"/>
    </Grid>

出现如下样式,则证明引入成功

wpf + MaterialDesign + Prism8 实现导航功能_Prism_04

 3、改造MainView

先贴出MainView.xaml 代码如下:

<Window x:Class="WpfApp.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:WpfApp.Views"
        mc:Ignorable="d"
        xmlns:Prism="http://prismlibrary.com/"   
        Prism:ViewModelLocator.AutoWireViewModel="True"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" 
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}"
        Background="{DynamicResource MaterialDesignPaper}"
        TextElement.FontWeight="Medium"
        FontFamily="{materialDesign:MaterialDesignFont}"
        TextElement.FontSize="14" 
        WindowStyle="None" 
        WindowStartupLocation="CenterScreen"
        Title="MainView" Height="768" Width="1280">
    <Window.Resources>
        <ResourceDictionary>
            <!--<Style TargetType="ListBoxItem" x:Key="Ls">
                <Setter Property="MinHeight" Value="40"/>
                <Setter Property="BorderThickness" Value="4,0,4,0"/> 
            </Style>-->
        </ResourceDictionary>

    </Window.Resources>
    <materialDesign:DialogHost DialogTheme="Inherit"
                             Identifier="RootDialog"
                             SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}">

        <materialDesign:DrawerHost x:Name="drawerHost" IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}" Background="Transparent">
            <materialDesign:DrawerHost.LeftDrawerContent>
                <DockPanel MinWidth="220"  Background="Transparent">
                    <ToggleButton Margin="16"
                        HorizontalAlignment="Right"
                        DockPanel.Dock="Top"
                        IsChecked="{Binding ElementName=MenuToggleButton, Path=IsChecked, Mode=TwoWay}"
                        Style="{StaticResource MaterialDesignHamburgerToggleButton}" />

                    <ListBox ItemsSource="{Binding menuBars}" ItemContainerStyle="{StaticResource MyListBoxItemStyle}" x:Name="menubar">

                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="SelectionChanged">
                                <i:InvokeCommandAction Command="{Binding ListBoxItemChangedCommand}" CommandParameter="{Binding ElementName=menubar,Path=SelectedItem}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal" Background="Transparent" VerticalAlignment="Center">
                                    <materialDesign:PackIcon Kind="{Binding MenuIcon}" Margin="15,0"/>
                                    <TextBlock Text="{Binding MenuName}" Margin="10,0" FontSize="16"/>
                                </StackPanel>

                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </DockPanel>
            </materialDesign:DrawerHost.LeftDrawerContent>

            <DockPanel>
                <materialDesign:ColorZone Padding="16" x:Name="ColorZone"
                                  materialDesign:ElevationAssist.Elevation="Dp4"
                                  DockPanel.Dock="Top"
                                  Mode="PrimaryMid">
                    <DockPanel LastChildFill="False">
                        <StackPanel Orientation="Horizontal">
                            <ToggleButton x:Name="MenuToggleButton"
                            AutomationProperties.Name="HamburgerToggleButton"
                          
                            IsChecked="False"
                            Style="{StaticResource MaterialDesignHamburgerToggleButton}" />

                            <Button Margin="24,0,0,0"
                      materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"
                      Command="{Binding BtnBack}"
                      Content="{materialDesign:PackIcon Kind=ArrowLeft,
                                                        Size=24}"
                      Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"
                      Style="{StaticResource MaterialDesignToolButton}"
                      ToolTip="Previous Item" Cursor="Hand" />

                            <Button Margin="16,0,0,0"
                      materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"
                      Command="{Binding BtnForward}"
                      Content="{materialDesign:PackIcon Kind=ArrowRight,
                                                        Size=24}"
                      Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"
                      Style="{StaticResource MaterialDesignToolButton}"
                      ToolTip="Next Item" Cursor="Hand" />

                            <Button Margin="16,0,0,0"
                      materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"
                      Command="{Binding HomeCommand}"
                      Content="{materialDesign:PackIcon Kind=Home,
                                                        Size=24}"
                      Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"
                      Style="{StaticResource MaterialDesignToolButton}"
                      ToolTip="Home" />
                        </StackPanel>


                        <TextBlock Margin="20,0,0,0"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       AutomationProperties.Name="Material Design In XAML Toolkit"
                       FontSize="22"
                       Text="Material Design In XAML Toolkit" />

                        <StackPanel DockPanel.Dock="Right"  Orientation="Horizontal">
                            <TextBlock Text="hi,wpf" Margin="0 ,8,10,0" FontSize="18" Foreground="#ffc"/>
                            <Image Source="/images/tx.jpg" Width="25" Height="25" Margin="10 0">
                                <Image.Clip>
                                    <EllipseGeometry RadiusX="12.5" RadiusY="12.5" Center="12.5,12.5"/>
                                </Image.Clip>
                            </Image>
                            <Button x:Name="btnMin" Content="―" Margin="5 0"/>
                            <Button x:Name="btnMax" Content="☐" Margin="5 0"/>
                            <Button x:Name="btnClose" Content="✕" Margin="5 0"/>
                        </StackPanel>
                    </DockPanel>


                </materialDesign:ColorZone>


                <ContentControl  Prism:RegionManager.RegionName="MainViewRegionName" />
            </DockPanel>


        </materialDesign:DrawerHost>
    </materialDesign:DialogHost>
</Window>

View Code

3.1、针对xaml说明如下:

<Window x:Class="WpfApp.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:WpfApp.Views"
        mc:Ignorable="d"
        xmlns:Prism="http://prismlibrary.com/"   --引入Prism命名空间
        Prism:ViewModelLocator.AutoWireViewModel="True"  --根据Prism规则,自动匹配数据上下文DataContext
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"  --引入MaterialDesgin 样式库
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"  --引入行为,用于处理ListBoxItem点击事件
        TextElement.Foreground="{DynamicResource MaterialDesignBody}" --引入 MaterialDesign 颜色
        Background="{DynamicResource MaterialDesignPaper}"  --引入动态资源
        TextElement.FontWeight="Medium"  --引入MaterialDesign 字体
        FontFamily="{materialDesign:MaterialDesignFont}"  --引入 materialDesign 字体
        TextElement.FontSize="14"  --设置字号
        WindowStyle="None"   --去掉窗体边框
        WindowStartupLocation="CenterScreen"  --启动后,默认居中
        Title="MainView" Height="768" Width="1280">

3.2、双击事件、最大、最小按钮事件、拖拽事件


/// <summary>
    /// MainView.xaml 的交互逻辑
    /// </summary>
    public partial class MainView : Window
    {
        public MainView()
        {
            InitializeComponent();
            //最小化
            btnMin.Click += (s, e) => { this.WindowState = WindowState.Minimized; };
            //最大化
            btnMax.Click += (s, e) =>
            {
                if (this.WindowState == WindowState.Normal)
                {
                    this.WindowState = WindowState.Maximized;
                }
                else
                {
                    this.WindowState = WindowState.Normal;
                }
            };
            //关闭事件
            btnClose.Click += (s, e) => { this.Close(); };
            //鼠标拖拽事件
            ColorZone.MouseMove += (s, e) =>
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    this.DragMove();
                }
            };

            //鼠标双击导航栏事件
            ColorZone.MouseDoubleClick += (s, e) =>
            {
                if (this.WindowState == WindowState.Normal)
                {
                    this.WindowState = WindowState.Maximized;
                }
                else
                {
                    this.WindowState = WindowState.Normal;
                }
            };

            menubar.SelectionChanged += (s, e) =>
            {
                drawerHost.IsLeftDrawerOpen = false;
            };
        }
    }

View Code

3.3、MainViewModel如下:

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace WpfApp.ViewModels
{
    public class MainViewModel : BindableBase
    {
        public ObservableCollection<MenuBarDto> menuBars { get; set; }
        public DelegateCommand<MenuBarDto> ListBoxItemChangedCommand { get; private set; }
        public DelegateCommand BtnBack { get; private set; }
        public DelegateCommand BtnForward { get; private set; }
        /// <summary>
        /// 区域管理器-跳转相关
        /// </summary>
        private readonly IRegionManager regionManager;
        /// <summary>
        /// 用于保存路由跳转记录
        /// </summary>
        private IRegionNavigationJournal journal;

        public MainViewModel(IRegionManager regionManager)
        {
            CreateMenus();
            this.regionManager = regionManager;
            ListBoxItemChangedCommand = new DelegateCommand<MenuBarDto>(GoMenuBar);
            BtnBack = new DelegateCommand(Back);
            BtnForward = new DelegateCommand(Forward);
        }

        private void GoMenuBar(MenuBarDto obj)
        {
            //参考:MainView.Xaml 中的 <ContentControl  Prism:RegionManager.RegionName="MainViewRegionName" />
            regionManager.Regions["MainViewRegionName"].RequestNavigate(obj.MenuPath, navigationCallback);

        }

        private void navigationCallback(NavigationResult obj)
        {
            if (obj.Result.Value)
            {
                //如果跳转成功,则存储跳转记录
                journal = obj.Context.NavigationService.Journal;
            }
        }
        /// <summary>
        /// 返回上一页
        /// </summary>
        private void Back()
        {
            if (journal != null && journal.CanGoBack)
            {
                journal.GoBack();
            }
        }

        /// <summary>
        /// 返回下一页
        /// </summary>
        private void Forward()
        {
            if (journal != null && journal.CanGoForward)
            {
                journal.GoForward();
            }
        }

        private void CreateMenus()
        {
            menuBars = new ObservableCollection<MenuBarDto>();
            menuBars.Add(new MenuBarDto() { MenuIcon = "Home", MenuName = "首页", MenuPath = "IndexView" });
            menuBars.Add(new MenuBarDto() { MenuIcon = "User", MenuName = "用户管理", MenuPath = "UserView" });
            menuBars.Add(new MenuBarDto() { MenuIcon = "NotebookOutline", MenuName = "备忘录", MenuPath = "MemoView" });
            menuBars.Add(new MenuBarDto() { MenuIcon = "Cog", MenuName = "设置", MenuPath = "SetingView" });
        }
    }

    public class MenuBarDto
    {
        public string MenuName { get; set; }
         
        public string MenuIcon { get; set; }
      
        public string MenuPath { get; set; } 

    }
}

View Code

说明如下:

上述代码设计 导航跳转,导航记录,上一页,下一页等功能,不懂的小伙伴这里就不解释了。

最终效果图:

wpf + MaterialDesign + Prism8 实现导航功能_Prism_05

 



标签:System,private,MaterialDesign,WindowState,Prism,using,wpf,Prism8,public
From: https://blog.51cto.com/u_15316082/8983333

相关文章

  • WPF 装饰器 、 转换器 、行为
    十年河东,十年河西,莫欺少年穷学无止境,精益求精行为请参考:WPF行为 装饰器参考: wpf转换器详情参考:单值转换器需继承自IValueConverterpublicclassMyNumberConverter:IValueConverter{publicobjectConvert(objectvalue,TypetargetType,objectparameter,......
  • wpf + MaterialDesign + Prism8 实现导航功能
    十年河东,十年河西,莫欺少年穷学无止境,精益求精实现的效果: 1、初始化Prism 1.1、项目引入如下包 1.2、按照Prism规则,项目中创建如下文件夹 Prism规则:必须将窗体放入Views文件夹中,窗体名称必须以View结尾,必须将数据上下文放入ViewModels文件夹中,上下文类必须以Model结尾另外两个......
  • WPF+SqlSugar+MVVM实现增删改查(二)
    这相对于上一版本的升级版如果不理解看请看第一版:WPF+SqlSugar+MVVM实现增删改查-六子12138-博客园(cnblogs.com)ViewModels代码1usingEntitys;2usingSqlSugar;3usingSystem;4usingSystem.Collections.Generic;5usingSystem.Collections.Object......
  • wpf + MaterialDesign + Prism8 + DataGrid 实现表格内数据编辑,下拉
    十年河东,十年河西,莫欺少年穷学无止境,精益求精效果如下: xaml如下:<UserControlx:Class="WpfApp.UserControls.MemoView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/w......
  • WPF Halcon机器视觉和运动控制软件通用框架,插件式开发,开箱即用 仅供学习!
    点我下载,仅供个人学习使用参考easyvision开发,集成几十个软件算子此版本以添加ui设计器。具体功能如上所示,可以自定义变量,写c#脚本,自定义流程,包含了halcon脚本和封装的算子,可自定义ui,通过插件形式开发很方便拓展自己的功能。......
  • wpf + MaterialDesign + Prism8 + DataGrid 实现表格数据+分页
    十年河东,十年河西,莫欺少年穷学完止境,精益求精1、不分页,带有排序功能(每个字段都可以排序) xaml如下:<UserControlx:Class="WpfApp.UserControls.UserView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http:......
  • 深入理解WPF中的Dispatcher:优化UI操作的关键
     概述:Dispatcher是WPF中用于协调UI线程和非UI线程操作的关键类,通过消息循环机制确保UI元素的安全更新。常见用途包括异步任务中的UI更新和定时器操作。在实践中,需注意避免UI线程阻塞、死锁,并使用CheckAccess方法确保在正确的线程上执行操作。这有助于提升应用程序的性能和用户......
  • 使用MVVM Toolkit简化WPF开发
    最近.NET8的WPF推出了 WPFFileDialog改进,这样无需再引用 Win32 命名空间就可以实现文件夹的选择与存储了,算是一个很方便的改进了。顺手写了一个小的WPF程序,在使用 Model-View-ViewModel(MVVM) 模式的时候,我不想使用 Prism 等重量级的框架,找了一个轻量级的MVVMCo......
  • 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发
    https://www.cnblogs.com/wuhuacong/tag/WPF/ 在我们的SqlSugar的开发框架中,整合了Winform端、Vue3+ElementPlus的前端、以及基于UniApp+Vue+ThorUI的移动前端几个前端处理,基本上覆盖了我们日常的应用模式了,本篇随笔进一步介绍前端应用的领域,研究集成WPF的应用端,循序渐进介绍基......
  • WPF MvvmToolkit入门
    最新.net6wpfMVVMToolkit8.0工程搭建。MVVMToolkit是一个轻量级MVVM框架,在框架下我们第一个要做的就是搞清在此框架下的一些常规操作:属性绑定和通知,命令绑定,消息传递。搞懂这些处理流程,然后就可以写自己业务的逻辑。1.安装mvvmtoolkit1.1Nuget下载CommunityToolkit.Mvvm......