WFP实现侧边栏导航菜单

news2024/11/24 3:49:33

菜单导航功能实现,常规的管理系统应该常用,左侧显示菜单条目,点击菜单,右侧切换不同的业务用户控件。

常用菜单可以采用TreeView树形控件+特定样式实现 ,本文介绍的是使用Expander+ListView的组合形式实现的导航菜单,两种各有各的好处,本文不做优劣评价。

需要添加两个Nuget库:MaterialDesignThemes和MaterialDesignColors,本程序是使用该控件库实现的,非常强大

文件说明:

  • App.xaml:只引入MD控件样式。
  • MainWindow.展示导航菜单及控制菜单对应的用户控件切换。
  • UserControlMenuItem为单个菜单用户控件,由 Expander+ListView的组合形式实现 。
  • UserControlCustomers和UserControlProviders作为两个举例用的业务用户控件。
  • ViewModel中定义的两个菜单相关的类,将菜单及业务用户控件关联。

App.xaml引入MD控件样式

<Application x:Class="侧边栏导航菜单_Dropdown_Menu_.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:侧边栏导航菜单_Dropdown_Menu_"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Indigo.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

主窗体

MainWindow.xaml,整体布局,看上图加上下面的界面代码,添加界面左上角logo图标、左侧导航菜单、右侧业务控件显示容器等。

<Window x:Class="侧边栏导航菜单_Dropdown_Menu_.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:侧边栏导航菜单_Dropdown_Menu_"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        mc:Ignorable="d"
        Title="下拉菜单" Height="450" Width="800" WindowStartupLocation="CenterScreen" WindowState="Maximized">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <materialDesign:ColorZone Mode="PrimaryMid" Grid.ColumnSpan="2" HorizontalAlignment="Stretch">
            <Grid>
                <materialDesign:PopupBox PlacementMode="BottomAndAlignRightEdges" HorizontalAlignment="Right" Margin="10"/>
            </Grid>
        </materialDesign:ColorZone>
        <Grid HorizontalAlignment="Stretch" Grid.Row="1" Background="{StaticResource PrimaryHueMidBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="70"/>
                <RowDefinition Height="326*"/>
            </Grid.RowDefinitions>
            <Grid Grid.Row="0" Background="GhostWhite">
                <Image Source="Assets/logo.png"/>
            </Grid>
            <ScrollViewer HorizontalAlignment="Stretch" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Grid.Row="1">
                <StackPanel x:Name="Menu" Margin="10"/>
            </ScrollViewer>
        </Grid>
        <StackPanel x:Name="StackPanelMain" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch">

        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs,主窗体后台代码,没啥好说的,初始化菜单绑定数据、切换菜单显示用户控件。

using 侧边栏导航菜单_Dropdown_Menu_.ViewModel;
using MaterialDesignThemes.Wpf;
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;

namespace 侧边栏导航菜单_Dropdown_Menu_
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var menuRegister = new List<SubItem>();
            menuRegister.Add(new SubItem("客户", new UserControlCustomers()));
            menuRegister.Add(new SubItem("供应商", new UserControlProviders()));
            menuRegister.Add(new SubItem("员工"));
            menuRegister.Add(new SubItem("产品"));
            var item6 = new ItemMenu("登记", menuRegister, PackIconKind.Register);

            var menuSchedule = new List<SubItem>();
            menuSchedule.Add(new SubItem("服务"));
            menuSchedule.Add(new SubItem("会议"));
            var item1 = new ItemMenu("预约", menuSchedule, PackIconKind.Schedule);

            var menuReports = new List<SubItem>();
            menuReports.Add(new SubItem("客户"));
            menuReports.Add(new SubItem("供应商"));
            menuReports.Add(new SubItem("产品"));
            menuReports.Add(new SubItem("库存"));
            menuReports.Add(new SubItem("销售额"));
            var item2 = new ItemMenu("报告", menuReports, PackIconKind.FileReport);

            var menuExpenses = new List<SubItem>();
            menuExpenses.Add(new SubItem("固定资产"));
            menuExpenses.Add(new SubItem("流动资金"));
            var item3 = new ItemMenu("费用", menuExpenses, PackIconKind.ShoppingBasket);

            var menuFinancial = new List<SubItem>();
            menuFinancial.Add(new SubItem("现金流"));
            var item4 = new ItemMenu("财务", menuFinancial, PackIconKind.ScaleBalance);

            Menu.Children.Add(new UserControlMenuItem(item6, this));
            Menu.Children.Add(new UserControlMenuItem(item1, this));
            Menu.Children.Add(new UserControlMenuItem(item2, this));
            Menu.Children.Add(new UserControlMenuItem(item3, this));
            Menu.Children.Add(new UserControlMenuItem(item4, this));
        }

        internal void SwitchScreen(object sender)
        {
            var screen = ((UserControl)sender);

            if (screen != null)
            {
                StackPanelMain.Children.Clear();
                StackPanelMain.Children.Add(screen);
            }
        }
    }
}

导航子菜单用户控件

UserControlMenuItem.xaml

<UserControl x:Class="侧边栏导航菜单_Dropdown_Menu_.UserControlMenuItem"
             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:侧边栏导航菜单_Dropdown_Menu_"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             mc:Ignorable="d">
    <Grid>
        <materialDesign:PackIcon Kind="{Binding Icon}" Width="15" Height="15" Margin="10 16" Foreground="White"/>
        <ListBoxItem x:Name="ListViewItemMenu" Content="{Binding Header}" Padding="37 14" FontSize="15" Foreground="White"/>
        <Expander x:Name="ExpanderMenu" Header="{Binding Header}" IsExpanded="False" Width="210" HorizontalAlignment="Right" Background="{x:Null}" Foreground="White">
            <ListView x:Name="ListViewMenu" ItemsSource="{Binding SubItems}" Foreground="White" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="ListViewMenu_SelectionChanged">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" Padding="20 5"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Expander>
    </Grid>
</UserControl>

UserControlMenuItem.xaml.cs,后台代码实现

using 侧边栏导航菜单_Dropdown_Menu_.ViewModel;
using System;
using System.Collections.Generic;
using System.Text;
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;

namespace 侧边栏导航菜单_Dropdown_Menu_
{
    /// <summary>
    /// UserControlMenuItem.xaml 的交互逻辑
    /// </summary>
    public partial class UserControlMenuItem : UserControl
    {
        MainWindow _context;
        public UserControlMenuItem(ItemMenu itemMenu, MainWindow context)
        {
            InitializeComponent();

            _context = context;

            ExpanderMenu.Visibility = itemMenu.SubItems == null ? Visibility.Collapsed : Visibility.Visible;
            ListViewItemMenu.Visibility = itemMenu.SubItems == null ? Visibility.Visible : Visibility.Collapsed;

            this.DataContext = itemMenu;
        }

        private void ListViewMenu_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _context.SwitchScreen(((SubItem)((ListView)sender).SelectedItem).Screen);
        }
    }
}

菜单ViewModel类

ItemMenu.cs

using MaterialDesignThemes.Wpf;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;

namespace 侧边栏导航菜单_Dropdown_Menu_.ViewModel
{
    public class ItemMenu
    {
        public ItemMenu(string header, List<SubItem> subItems, PackIconKind icon)
        {
            Header = header;
            SubItems = subItems;
            Icon = icon;
        }

        public string Header { get; private set; }
        public PackIconKind Icon { get; private set; }
        public List<SubItem> SubItems { get; private set; }
        public UserControl Screen { get; private set; }
    }
}

SubItem.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;

namespace 侧边栏导航菜单_Dropdown_Menu_.ViewModel
{
    public class SubItem
    {
        public SubItem(string name, UserControl screen = null)
        {
            Name = name;
            Screen = screen;
        }
        public string Name { get; private set; }
        public UserControl Screen { get; private set; }
    }
}

两个举例用的用户控件

UserControlCustomers.xaml

<UserControl x:Class="侧边栏导航菜单_Dropdown_Menu_.UserControlCustomers"
             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:侧边栏导航菜单_Dropdown_Menu_"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="150"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Border Margin="5" Grid.Column="0" Background="#FFC5C5C5" VerticalAlignment="Stretch" CornerRadius="12"/>
        <Border Margin="5" Grid.Column="1" Background="#FF7C54A0" VerticalAlignment="Stretch" CornerRadius="12"/>
        <Border Margin="5" Grid.Column="2" Background="#FF83CD80" VerticalAlignment="Stretch" CornerRadius="12"/>
        <Border Margin="5" Grid.Column="3" Background="#FFEE9246" VerticalAlignment="Stretch" CornerRadius="12"/>
    </Grid>
</UserControl>

UserControlProviders.xaml

<UserControl x:Class="侧边栏导航菜单_Dropdown_Menu_.UserControlProviders"
             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:侧边栏导航菜单_Dropdown_Menu_"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="150"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Border Margin="5" Grid.Column="0" Background="#FFD4E436" VerticalAlignment="Stretch" CornerRadius="12"/>
        <Border Margin="5" Grid.Column="1" Background="#FF81F9FF" VerticalAlignment="Stretch" CornerRadius="12"/>
        <Border Margin="5" Grid.Column="2" Background="#FF144BC3" VerticalAlignment="Stretch" CornerRadius="12"/>
        <Border Margin="5" Grid.Column="3" Background="#FFD34EBA" VerticalAlignment="Stretch" CornerRadius="12"/>
    </Grid>
</UserControl>

文章中代码几乎已经全部贴出,就是这么多。

效果如下:

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法day24|理论基础77

详细布置 理论基础 什么是回溯法&#xff1a;递归函数下面通常有回溯法 它使用的地方&#xff1a;组合&#xff0c;切割&#xff0c;子集&#xff0c;排列&#xff0c;棋盘问题&#xff08;N皇后&#xff0c;解数独&#xff09; 回溯算法的模板: void backtracking(参数)&…

微型计算机基础

微型计算机常用术语 位&#xff08;bit&#xff09;&#xff1a;计算机所能表示的最基本&#xff0c;最小的数据单元。1个二进制位有两种状态0和1 通常情况下0表示低电平&#xff08;接地&#xff09;&#xff0c;1表示高电平接电源&#xff08;VCC&#xff09; 字节&#xff0…

MATLAB 矩阵处理及多项式计算

一、实验目的 &#xff08;1&#xff09;掌握生成特殊矩阵以及矩阵处理的方法 &#xff08;2&#xff09;掌握数据统计和分析的方法 &#xff08;3&#xff09;掌握多项式的常用计算 二、实验原理与实验设备 原理&#xff1a;计算机编程相关知识技能和MATLAB软件编译环境 …

c++——map和set的封装

注&#xff1a;该封装基于前面博客已实现红黑树&#xff0c;map和set封装并不难&#xff0c;主要还是对红黑树的理解 目录 一. 改造红黑树 1. 改变节点的定义&#xff0c;使用更高维度的泛型 2. 红黑树追加迭代器的实现 1. 红黑树迭代器的构造函数和基本框架 2. begin()和e…

2.4、编码与调制

2.4、编码与调制 在计算机网络中。计算机需要处理和传输用户的文字&#xff0c;图片&#xff0c;音频和视频。它们可以统称为消息。 数据是运送消息的实体。 计算机中的网卡将比特 000 和 111&#xff0c;变换成相应的电信号发送到网线。 也就是说&#xff0c;信号是数据的…

[附源码]java毕业设计网络学习平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

LeetCode力扣刷题——更加复杂的数据结构

更加复杂的数据结构 一、引言 目前为止&#xff0c;我们接触了大量的数据结构&#xff0c;包括利用指针实现的三剑客和 C 自带的 STL 等。 对于一些题目&#xff0c;我们不仅需要利用多个数据结果解决问题&#xff0c;还需要把这些数据结构进行嵌套和联 动&#xff0c;进行更为…

五.STM32F030C8T6 MCU开发之RTC模块基础例程

五.STM32F030C8T6 MCU开发之RTC模块基础例程 文章目录五.STM32F030C8T6 MCU开发之RTC模块基础例程0.总体功能概述1.RTC硬件介绍1.1日历的功能1.2 闹钟输出1.3 入侵检测1.4 时间戳事件检测2.RTC软件配置2.1.RTC 模块初始化配置2.2 RTC 开始时间配置2.2.1RTC 年月日 时分秒配置2.…

_linux 进程间通信(管道)

文章目录1. 进程间通信目的2. 进程间通信发展3. 进程间通信分类4. 管道1. 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#x…

【English】十大词性之介词

介词 文章目录介词前言一、方位介词1.1 某地1.2 里里外外1.3 上上下下1.4 前前后后1.5 ....中间1.6 ...穿越1.7 ...树上1.8 在...墙上1.9 旁边(距离远近区分)二、时间介词三、方式介词四、易混淆介词4.1 制成4.2 交通工具4.3 除了总结前言 介词是表示名词、代词与句子中其它词…

02Java线程模型

1. 操作系统线程 无论使用何种编程语言编写多线程程序&#xff0c;最终都是通过调用操作系统的线程来执行任务。线程是CPU调度的最小执行单元。 线程有多种实现方式&#xff0c;常见的有&#xff1a;内核线程、用户线程、混合线程。 不同线程模型的主要区别在于线程的调度方不…

【Ubuntu】配置ubuntu网络

配置ubuntu网络 一、三种虚拟网络介绍二、 配置ubuntu系统使用桥接模式连接外网三、通过NAT模式让ubuntu系统连接外网四、常见问题1.解决ubuntu系统没有网络图标一、三种虚拟网络介绍 VMnet0 : 桥接模式,选中桥接模式之后,可以将VMnet0桥接到对应的物理网卡之上, 默认选中自…

uniapp公共新闻模块components案例

uniapp公共新闻模块components案例 简介&#xff1a;本文使用uniapp的公共新闻模块讲解components案例。 效果展示&#xff1a; 第一步 创建公共模块 第二步 编写组件 <template><view class"newsbox"><view class"pic"><ima…

动态路由协议 OSPF 工作过程 之 状态机维度

状态机 &#xff1a; # 什么是状态机呢 &#xff1f; 状态机 &#xff1a; 就是 OSPF 路由间的邻居关系所在的不同阶段 不同的关系 就是 不同的状态机 OSPF 的状态机 &#xff1a; # 我们用 思科 的PPT 来介绍 OSPF 的状态机 # 里面所有黄颜色方框里 标定的就是 状态机…

Json格式API调试,taobao1688pinduoduo商品详情测试接口

Json常用类型 任何支持的类型都可以通过 JSON 来表示&#xff0c;例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型。 对象&#xff1a;对象在 JS 中是使用花括号包裹 {} 起来的内容&#xff0c;数据结构为 {key1&#xff1a;value1, key2&#xf…

JavaScript:生成器函数

在介绍生成器函数之前先了解一下ES6的一个关键字&#xff0c;名为yield yield关键字&#xff0c;可以让代码在其出现的地方暂停执行&#xff0c;它只能在生成器函数内部使用。 生成器函数 生成器函数的语法比较简单在普通函数声明的时候在函数名前面添加一个*即可&#xff0…

openxr runtime Monado 源码解析 源码分析:Prober设备发现和管理 system device HMD target instance

monado系列文章索引汇总&#xff1a;openxr runtime Monado 源码解析 源码分析&#xff1a;源码编译 准备工作说明 hello_xr解读openxr runtime Monado 源码解析 源码分析&#xff1a;整体介绍 模块架构 模块作用 进程 线程模型 整体流程openxr runtime Monado 源码解析 源码分…

计算机网络4小时速成:物理层,功能特性,通信系统模型,分类,调制,曼彻斯特编码,信噪比,香农定理,复用技术,同轴电缆,中继器

计算机网络4小时速成&#xff1a;物理层&#xff0c;功能特性&#xff0c;通信系统模型&#xff0c;分类&#xff0c;调制&#xff0c;曼彻斯特编码&#xff0c;信噪比&#xff0c;香农定理&#xff0c;复用技术&#xff0c;同轴电缆&#xff0c;中继器 2022找工作是学历、能力…

[附源码]计算机毕业设计JAVA基于jsp的网上点餐系统

[附源码]计算机毕业设计JAVA基于jsp的网上点餐系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM m…

Proxy 代理对象使用详解即原理总结

Proxy 代理对象使用详解即原理总结 Proxy简单介绍 ECMAscript 6新增的代理可以给目标对象定义一个关联的代理对象&#xff0c;而这个代理对象可以作为抽象的目标对象来使用&#xff0c;在对目标对象的各种操作影响目标对象之前&#xff0c;可以在代理对象中对这些操作加以控制…