Wpf 使用 Prism 实战开发Day09

设置模块设计

1.效果图

一.系统设置模块,主要有个性化(用于更改主题颜色),系统设置,关于更多,3个功能点。

个性化的颜色内容样式,主要是从 Material Design Themes UI简称md、提供的demo里复制代码过来使用的。

 1.设置模块里面左侧导航栏(个性化、系统设置、关于更多)实现,该功能点主要用到Prism 框架的导航模块来实现。 


  • 整体设置界面布局,主要分上下2行,第1行是设置字体以及一条横线。第2行放置整个左侧导航栏以及展现对应的动态内容。
  • 横线使用 Border 来实现 ,设置颜色属性 BorderBrush,设置粗细属性 BorderThickness
  • 第2行,根据内容布局,重新在Grid 里面创建 2列。例如,1列用于放置导航栏左侧菜单,2列用于放置,当点击导航栏菜单时动态展现的内容区域。

SettingsView.xaml  

<UserControl x:Class="MyToDo.Views.SettingsView"
             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:MyToDo.Views"
             mc:Ignorable="d" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:prism="http://prismlibrary.com/"
             xmlns:ext="clr-namespace:MyToDo.Extensions"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition  Height="auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Text="设置" FontSize="26" Margin="20,10"/>
        <Border BorderBrush="#DDDDDD" BorderThickness="0,0,0,0.3"/>

        <Grid Grid.Row="1" Margin="50">
            <Grid.ColumnDefinitions>
                <ColumnDefinition  Width="220"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <!--左侧菜单栏-->
            <ListBox x:Name="menuBar" ItemContainerStyle="{StaticResource MyListBoxItemStyle}" ItemsSource="{Binding MenuBars}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <i:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{Binding ElementName=menuBar,Path=SelectedItem}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" Background="Transparent">
                            <materialDesign:PackIcon Kind="{Binding Icon}" Margin="15,0" />
                            <TextBlock Text="{Binding Title}" Margin="10,0"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <!--右侧菜单栏内容区域,动态区域。根据导航栏切换不同的页面-->

            <ScrollViewer  Grid.Column="1">
                <ContentControl Margin="10,0" prism:RegionManager.RegionName="{x:Static ext:PrismManager.SettingsViewRegionName}"/>
            </ScrollViewer>
           
        </Grid>
    </Grid>
</UserControl>
  1.  MyListBoxItemStyle 是App.xaml 里定义的一个静态资源文件。
  2.   App.xaml 文件源码在第3章节

 PrismManager 导航区域名称管理扩展类,添加设置页区域动态展示内容区域一个名称。

    public static class PrismManager
    {
        /// <summary>
        /// 首页区域
        /// </summary>
        public static readonly string MainViewRegionName = "MainViewReion";

        /// <summary>
        /// 设置页区域
        /// </summary>
        public static readonly string SettingsViewRegionName = "SettingsViewRegionName";

    }

左侧导航菜单栏对应后端逻辑代码 实现

SettingsViewModel.cs

public class SettingsViewModel: BindableBase
{
    public SettingsViewModel(IRegionManager regionManager)
    {
        MenuBars=new ObservableCollection<MenuBar>();
        NavigateCommand = new DelegateCommand<MenuBar>(Navigate);
        this.regionManager = regionManager;
        CreateMenuBar();
    }
    /// <summary>
    /// 导航命令
    /// </summary>
    public DelegateCommand<MenuBar> NavigateCommand { get; private set; }


    private ObservableCollection<MenuBar> menuBars;
    private readonly IRegionManager regionManager;
    /// <summary>
    /// 导航日志
    /// </summary>
    private IRegionNavigationJournal journal;
    public ObservableCollection<MenuBar> MenuBars
    {
        get { return menuBars; }
        set { menuBars = value; RaisePropertyChanged(); }
    }
    void CreateMenuBar()
    {
        MenuBars.Add(new MenuBar() { Icon = "Bowling", Title = "个性化", NameSpace = "SkinView" });
        MenuBars.Add(new MenuBar() { Icon = "CogOutline", Title = "系统设置", NameSpace = "" });
        MenuBars.Add(new MenuBar() { Icon = "InformationOutline", Title = "关于更多", NameSpace = "AboutView" });
    }
    /// <summary>
    /// 导航方法
    /// </summary>
    /// <param name="bar">菜单</param>
    private void Navigate(MenuBar bar)
    {
        //命名空间为空,不进行导航
        if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;

        regionManager.Regions[PrismManager.SettingsViewRegionName].RequestNavigate(bar.NameSpace);
    }
}

完成以上步骤后,就能显示左侧菜单导航栏了。


2.左侧菜单点击时,右侧区域需动态展示对应的内容

  • 当点击对应的导航菜单,例如个性化或系统设置或关于更多时,右侧需要根据不同的导航菜单,动态展现不同的内容。
  • 需要创建右侧内容区域对应的视图(V)-业务逻辑(VM)-实体类(M),俗称MVVM 模式。

以个性化 (SkinView)为例:只需要创建SkinView.xaml 和 SkinViewModel

创建完毕后,需要在 App.xaml.cs 中,进行模块注入。

 containerRegistry.RegisterForNavigation<SkinView, SkinViewModel>();


 二.个性化(SkinView)页面功能实现

  1. 个性化内容页面分上下2行,只需要创建一个2行即可。 
  2. 添加命名空间  xmlns:materialDesignColors="clr-namespace:MaterialDesignColors;assembly=MaterialDesignColors"
  3. UserControl.Resources 表示当前用户控件的资源文件(当前窗口的资源文件)
  4. RelativeSource={RelativeSource AncestorType=local:SkinView} 表示的是查找绑定,需要绑定到当前的SkinView
  5. 添加颜色转换器
  6. 转换器命名空间 xmlns:converters="clr-namespace:MyToDo.Common.Converters"

SkinView.xaml

<UserControl x:Class="MyToDo.Views.SkinView"
             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:MyToDo.Views"
             xmlns:materialDesignColors="clr-namespace:MaterialDesignColors;assembly=MaterialDesignColors"
             xmlns:converters="clr-namespace:MyToDo.Common.Converters"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <!--当前窗口的资源文件-->
    <UserControl.Resources>
        <converters:ColorToBrushConverter x:Key="ColorToBrushConverter" />
        <DataTemplate x:Key="SwatchColorTemplate" DataType="{x:Type Color}">
            <Button Width="40"
          Height="40" BorderThickness="0" Margin="1"
          Background="{Binding Converter={StaticResource ColorToBrushConverter}}"
          Command="{Binding DataContext.ChangeHueCommand, RelativeSource={RelativeSource AncestorType=local:SkinView}}"
          CommandParameter="{Binding}">
            </Button>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" Margin="0,10">
            <TextBlock Text="浅色"/>
            <ToggleButton Margin="8 0 16 0" IsChecked="{Binding IsDarkTheme}"/>
            <TextBlock Text="深色"/>
        </StackPanel>

        <ItemsControl Grid.Row="1" ItemsSource="{Binding Swatches}">
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type materialDesignColors:ISwatch}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Width="80"
                   VerticalAlignment="Center"
                   Text="{Binding Name, Mode=OneTime}" />
                        <ItemsControl ItemTemplate="{StaticResource SwatchColorTemplate}" ItemsSource="{Binding Hues, Mode=OneTime}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel Orientation="Horizontal" />
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                        </ItemsControl>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</UserControl>

SkinViewModel.cs

public class SkinViewModel: BindableBase
{
    public SkinViewModel()
    {
        ChangeHueCommand = new DelegateCommand<object>(ChangeHue);
    }
    private bool _isDarkTheme=true;
    public bool IsDarkTheme 
    {
        get => _isDarkTheme;
        set
        {
            if(SetProperty(ref _isDarkTheme, value))
            {
                ModifyTheme(theme => theme.SetBaseTheme(value ? Theme.Dark : Theme.Light));
            }
        }
    }
    public IEnumerable<ISwatch> Swatches { get; } = SwatchHelper.Swatches;

    public DelegateCommand<object> ChangeHueCommand {  get; private set; }
    private readonly PaletteHelper paletteHelper = new PaletteHelper();
    private void ChangeHue(object? obj)
    {
        var hue = (Color)obj!;

        Theme theme = (Theme)paletteHelper.GetTheme();

        theme.PrimaryLight = new ColorPair(hue.Lighten());
        theme.PrimaryMid = new ColorPair(hue);
        theme.PrimaryDark = new ColorPair(hue.Darken());

        paletteHelper.SetTheme(theme);
    }
    private static void ModifyTheme(Action<Theme> modificationAction)
    {
        PaletteHelper paletteHelper = new PaletteHelper();
        Theme theme = (Theme)paletteHelper.GetTheme();

        modificationAction?.Invoke(theme);

        paletteHelper.SetTheme(theme);
    }
}

ColorToBrushConverter.cs   颜色转换器

    [ValueConversion(typeof(Color), typeof(Brush))]
    public class ColorToBrushConverter : IValueConverter
    {
        public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
        {
            if (value is Color color)
            {
                SolidColorBrush rv = new(color);
                rv.Freeze();
                return rv;
            }
            return Binding.DoNothing;
        }

        public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
        {
            if (value is SolidColorBrush brush)
            {
                return brush.Color;
            }
            return default(Color);
        }
    }

三.系统设置页以及关于更多页

  • 系统设置页是空,可根据需求开发
  • 关于更多页,也就是一些简介

例如,关于更多页设计。第一步,添加一个 用户控件,并且名称为AboutView.xaml。第二步,对用户控件进行注入。然后写功能。。。


注:个性化页面代码,均从Md框架中搬运过来的!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/301153.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud系列篇:核心组件之负载均衡组件

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.负载均衡组件是什么 二.负载均衡…

【ArcGIS微课1000例】0087:经纬度格式转换(度分秒转度、度转度分秒)

ArcGIS软件可以很方便的直接实现度分秒转度、度转度分秒。 文章目录 一、转换预览二、工具介绍三、案例解析一、转换预览 借助ArcGIS快速实现度分秒与度及其他格式的坐标转换。例如:度分秒→度 度分秒: 度: 二、工具介绍 转换坐标记法:将一个或两个字段包含的坐标记法从一…

OpenNL线性系统求解库

OpenNL 是一个用于求解大型稀疏线性系统的C开发库。 它包括一个易于使用的用于组装矩阵的 API&#xff0c;以及用于对称和非对称系统的各种迭代求解器。 OpenNL API 在 geogram/NL/nl.h 中声明。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/…

linux反汇编工具: ida pro、rizinorg/cutter; ubuntu 22 flameshot延迟截图 以应对下拉菜单

rizinorg/cutter rizinorg/cutter 是 命令行反汇编工具 rizinorg/rizin 的图形化界面, 这比 ida pro跑在kvm虚拟机中方便多了, ubuntu22.04下直接下载Cutter-v2.3.2-Linux-x86_64.AppImage后即可运行,如下图: 注意 有个同名的报废品: radare2/Cutter 即 radare2的图形化界…

TypeScript 从入门到进阶之基础篇(八)函数篇

系列文章目录 TypeScript 从入门到进阶系列 TypeScript 从入门到进阶之基础篇(一) ts基础类型篇TypeScript 从入门到进阶之基础篇(二) ts进阶类型篇TypeScript 从入门到进阶之基础篇(三) 元组类型篇TypeScript 从入门到进阶之基础篇(四) symbol类型篇TypeScript 从入门到进阶…

docker 安装elasticsearch、kibana、cerebro、logstash

安装步骤 第一步安装 docker 第二步 拉取elasticsearch、kibana、cerebro、logstash 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2 docker pull docker.elastic.co/kibana/kibana:7.10.2 docker pull lmenezes/cerebro:latest docker pull l…

ClickHouse基础知识(七):ClickHouse的分片集群

副本虽然能够提高数据的可用性&#xff0c;降低丢失风险&#xff0c;但是每台服务器实际上必须容纳全量数据&#xff0c;对数据的横向扩容没有解决。 要解决数据水平切分的问题&#xff0c;需要引入分片的概念。通过分片把一份完整的数据进行切 分&#xff0c;不同的分片分布到…

Vue知识总结-中

VUE-生命周期 生命周期概述 生命周期也常常被称为生命周期回调函数/生命周期函数/生命周期钩子生命周期是Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不能更改,但函数的具体内容是由我们程序员自己编写的生命周期函数中的this指向是vm或组件实例对象 生命周…

【Flutter 开发实战】Dart 基础篇:从了解背景开始

想要学会用 Flutter 开发 App&#xff0c;就不可避免的要学习另一门很有意思的编程语言 —— Dart。很多小伙伴可能在学习 Flutter 之前可能都没听说过这门编程语言&#xff0c;我也是一样&#xff0c;还以为 Dart 是为了 Flutter 而诞生的&#xff1b;然而&#xff0c;当我们去…

【嵌入式】Makefile 学习笔记记录 | 嵌入式Linux

文章目录 前言一、Makefile的引入——最简单的gcc编译过程二、Makefile的规则三、Makefile的语法3.1、通配符3.2、假想目标 .phony3.3、即时变量 延时变量 四、Makefile的函数4.1、foreach4.2、filter4.3、wildcard4.4、patsubst 五、Makefile升级5.1、包含头文件在内的依赖关系…

Force Yc 第六引导公告网页源码

Force Yc 第六引导公告网页源码,HTML源码&#xff0c;本地双击index.html即可运行,内容体积小&#xff0c;美观大气&#xff0c;二次元风格,喜欢的朋友可以拿去研究 蓝奏云&#xff1a;https://wfr.lanzout.com/iZsjv1kexkod

西电期末1035.可构造三角形个数

一.题目 二.分析与思路 依旧是遍历判断&#xff0c;三角形任意两边之和大于第三边&#xff0c;读题&#xff01;&#xff01;&#xff01;&#xff1a;连续的三个数&#xff01;&#xff01;&#xff01; 三.代码实现 #include<bits/stdc.h>//万能头 int main() {int …

机器视觉篇

1&#xff1a;实现LCD显示文字 实验名称&#xff1a;LCD 版本&#xff1a; v1.0 日期&#xff1a; 2022.12 作者&#xff1a; 01Studio 说明&#xff1a;编程实现LCD显示信息。需要将01Studio.bmp文件发送到开发板 import lcd,image,utimelcd.init() #初始化LCD lcd.clear(lcd…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第五天-Linux消息共享内存练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

案例介绍|钡铼助力2023年全国职业院校技能大赛工业网络智能控制与维护赛项

如今&#xff0c;越来越多的企业开始意识到数字制造和工业物联网已经成为工业自动化中大规模生产的核心驱动力。这其中&#xff0c;工业网络作为基础设施&#xff0c;是实现工厂设备联网与数据采集&#xff0c;建设数字工厂的基础和前提&#xff0c;甚至成为关乎数字工厂能否真…

【动态规划】C++算法312 戳气球

作者推荐 【动态规划】【字符串】扰乱字符串 本文涉及的基础知识点 动态规划 LeetCode312 戳气球 有 n 个气球&#xff0c;编号为0 到 n - 1&#xff0c;每个气球上都标有一个数字&#xff0c;这些数字存在数组 nums 中。 现在要求你戳破所有的气球。戳破第 i 个气球&…

PIG框架学习2——资源服务器的配置详解

一、前言 1、pig资源服务器的配置 Spring Security oauth2相关的依赖是在pigx-common-security模块中引入的&#xff0c;其他模块需要进行token鉴权的&#xff0c;需要在微服务中引入pigx-common-security模块的依赖&#xff0c;从而间接引入相关的Spring security oauth2依赖…

环境中碳循环

含碳的物质有CO2、CO、CH4、糖类、脂肪和蛋白质等&#xff0c;碳循环以CO2为中心&#xff0c;CO2被植物、藻类利用进行光合作用&#xff0c;合成植物性碳&#xff1b;动物摄食植物就将植物性碳转化为动物性碳&#xff1b;动物和人呼吸放出CO2&#xff0c;有机碳化合物被厌氧微生…

nodejs安装、nodejs环境变量配置、npm安装、vue安装

官网下载链接:https://nodejs.org/en/download/ 个人下载版本&#xff1a;node-v20.10.0-x64.msi&#xff0c;下载完成后&#xff0c;点击安装&#xff0c;除了更换安装目录&#xff0c;其他直接下一步即可 安装完成后执行&#xff1a;npm -v 下面开始配置环境变量&#xf…

Spring应用的部署与管理

一、前言 部署是将开发好的应用发布到服务器上&#xff0c;使其能够被用户访问的关键步骤。Spring框架提供了灵活的部署选项&#xff0c;本文将介绍Spring应用的常见部署方式和一些建议&#xff0c;帮助开发者顺利将应用投放到生产环境。 二、传统部署方式&#xff1a;WAR包 传…