有小伙伴问我有没有做过菜单栏,这我确实没做过,不过现在做还不晚吧,

先来做一个MenuItem,使用MVVM模式写,这样创建菜单的时候,只要绑定datacontext,就ok了,使用极为方便,还可以自定义颜色相关的属性。

先来看一下效果:

下面就来看看代码喽:

首先创建一个自定义控件类:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;namespace WPFDemos
{[DefaultProperty("MenuItems")][ContentProperty("MenuItems")][TemplatePart(Name = LB, Type = typeof(ListBox))]public class SideMenuItem : Control{private const string LB = "LB";private ListBox _listBox;public bool IsExpanded{get { return (bool)GetValue(IsExpandedProperty); }set { SetValue(IsExpandedProperty, value); }}public static readonly DependencyProperty IsExpandedProperty =DependencyProperty.Register("IsExpanded", typeof(bool), typeof(SideMenuItem), new PropertyMetadata(false));public List<object> MenuItems{get { return (List<object>)GetValue(MenuItemsProperty); }set { SetValue(MenuItemsProperty, value); }}public static readonly DependencyProperty MenuItemsProperty =DependencyProperty.Register("MenuItems", typeof(List<object>), typeof(SideMenuItem), new PropertyMetadata(default(List<object>)));public Brush ToggleBackground{get { return (Brush)GetValue(ToggleBackgroundProperty); }set { SetValue(ToggleBackgroundProperty, value); }}public static readonly DependencyProperty ToggleBackgroundProperty =DependencyProperty.Register("ToggleBackground", typeof(Brush), typeof(SideMenuItem), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(0x2d, 0x2d, 0x30))));public Brush MenuItemBackground{get { return (Brush)GetValue(MenuItemBackgroundProperty); }set { SetValue(MenuItemBackgroundProperty, value); }}public static readonly DependencyProperty MenuItemBackgroundProperty =DependencyProperty.Register("MenuItemBackground", typeof(Brush), typeof(SideMenuItem), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(0x16, 0x18, 0x1D))));public Brush MenuItemSelectedBackground{get { return (Brush)GetValue(MenuItemSelectedBackgroundProperty); }set { SetValue(MenuItemSelectedBackgroundProperty, value); }}public static readonly DependencyProperty MenuItemSelectedBackgroundProperty =DependencyProperty.Register("MenuItemSelectedBackground", typeof(Brush), typeof(SideMenuItem), new PropertyMetadata(Brushes.Green));public static readonly RoutedEvent MenuItemSelectedChangedEvent = EventManager.RegisterRoutedEvent("MenuItemSelectedChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SideMenuItem));public event RoutedEventHandler MenuItemSelectedChanged{add { AddHandler(MenuItemSelectedChangedEvent, value); }remove { RemoveHandler(MenuItemSelectedChangedEvent, value); }}public override void OnApplyTemplate(){base.OnApplyTemplate();_listBox = (GetTemplateChild(LB) as ListBox) ?? throw new Exception("listbox Named with \"LB\" not found in the Template");_listBox.SelectionChanged -= _listBoxSelectionChanged;_listBox.SelectionChanged += _listBoxSelectionChanged;}private void _listBoxSelectionChanged(object sender, SelectionChangedEventArgs e){if (!(e.Source is ListBox)) return;RoutedEventArgs args = new RoutedEventArgs(){RoutedEvent = MenuItemSelectedChangedEvent,Source = _listBox,};RaiseEvent(args);}}
}

然后创建一个控件的ViewModel类,BaseViewModel类就是大家都知道的基类,就不粘代码了,如果需要可以联系我:

using System.Collections.Generic;
using System.Windows.Media;
namespace WPFDemos
{public class SideMenuItemViewModel : BaseViewModel{private string _headerText;public string HeaderText{get { return _headerText; }set{_headerText = value;OnPropertyChanged(nameof(HeaderText));}}private List<object> _items = new List<object>();public List<object> Items{get { return _items; }set{_items = value;OnPropertyChanged(nameof(Items));}}private Geometry _iconGeometry;public Geometry IconGeometry{get { return _iconGeometry; }set {_iconGeometry = value;OnPropertyChanged(nameof(IconGeometry));}}}
}

然后在创建一个资源字典SideMenu.xaml,添加控件所需的样式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WPFDemos"><Geometry x:Key="DownGeometry">M445.406 731.963L93.35 339.737A87.354 87.354 0 0 1 71 281.387C71 233.123 110.15 194 158.444 194h704.111a87.476 87.476 0 0 1 58.39 22.336c35.95 32.226 38.951 87.474 6.704 123.4L575.593 731.964a87.415 87.415 0 0 1-6.705 6.7c-35.95 32.227-91.235 29.227-123.482-6.7z</Geometry><Geometry x:Key="UpGeometry">M575.594 216.037L927.65 608.263a87.354 87.354 0 0 1 22.35 58.35C950 714.877 910.85 754 862.556 754H158.445a87.476 87.476 0 0 1-58.39-22.336c-35.95-32.226-38.951-87.474-6.704-123.4l352.056-392.227a87.415 87.415 0 0 1 6.705-6.7c35.95-32.227 91.235-29.227 123.482 6.7z</Geometry><Geometry x:Key="IconInfo">M497 87c245.214 0 444 198.786 444 444S742.214 975 497 975 53 776.214 53 531 251.786 87 497 87z m1.15 331.275c-18.423 0-33.357 14.934-33.357 33.357v331.275c0 18.423 14.934 33.357 33.357 33.357 18.423 0 33.358-14.934 33.358-33.357V451.632c0-18.423-14.935-33.357-33.358-33.357zM497 254.938c-24.14 0-43.71 19.054-43.71 42.56 0 23.504 19.57 42.559 43.71 42.559s43.71-19.055 43.71-42.56c0-23.505-19.57-42.56-43.71-42.56z</Geometry><Style x:Key="ToggleButtonStyle1" TargetType="ToggleButton"><Setter Property="Background" Value="Transparent"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Padding" Value="0"/><Setter Property="Margin" Value="0"/><Setter Property="VerticalAlignment" Value="Center"/><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="BorderThickness" Value="0"/><Setter Property="HorizontalAlignment" Value="Center"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="ToggleButton"><Border SnapsToDevicePixels="true"BorderThickness="{TemplateBinding BorderThickness}"BorderBrush="{TemplateBinding BorderBrush}"Background="{TemplateBinding Background}"><ContentPresenter Name="UnCheckedElement"Margin="{TemplateBinding Padding}"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"RecognizesAccessKey="True"SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Opacity" Value="0.9"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter Property="Opacity" Value="0.6"/></Trigger><Trigger Property="IsEnabled" Value="False"><Setter Property="Opacity" Value="0.4"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style><Style x:Key="MenuHeaderStyle1" TargetType="Expander"><Setter Property="Foreground" Value="LightGray" /><Setter Property="Background" Value="#2D2D30" /><Setter Property="HorizontalContentAlignment" Value="Left" /><Setter Property="VerticalContentAlignment" Value="Center" /><Setter Property="BorderThickness" Value="0" /><Setter Property="MinHeight" Value="50" /><Setter Property="MinWidth" Value="220" /><Setter Property="FontSize" Value="14" /><Setter Property="Template" ><Setter.Value><ControlTemplate TargetType="Expander"><Grid><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="Auto" /></Grid.RowDefinitions><Border x:Name="BorderHeader"ClipToBounds="True"BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"><ToggleButton HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Focusable="False" Padding="10,0,0,0" Foreground="{TemplateBinding Foreground}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Width="{TemplateBinding Width}" Height="{TemplateBinding MinHeight}" Style="{StaticResource ToggleButtonStyle1}"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="40" /><ColumnDefinition /><ColumnDefinition Width="32" /></Grid.ColumnDefinitions><Path Name="PathIcon" IsHitTestVisible="False" Grid.Column="0" Stretch="Uniform" Fill="{TemplateBinding Foreground}" Height="16"Data="{Binding DataContext.IconGeometry,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:SideMenuItem}}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"HorizontalAlignment="Center" /><ContentPresenter ContentSource="Header" Grid.Column="1"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /><Path Name="PathArrow" IsHitTestVisible="False" Grid.Column="2" Stretch="Uniform" Fill="{TemplateBinding Foreground}" Data="{StaticResource DownGeometry}" Margin="0,0,10,0" Width="12" Height="12" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"HorizontalAlignment="Center" /></Grid></ToggleButton></Border><Border x:Name="LeftFlag" Width="5" Visibility="Collapsed" Background="#009688" HorizontalAlignment="Left"/><ContentPresenter Name="ExpandSite" Visibility="Collapsed" Grid.Row="1" /></Grid><ControlTemplate.Triggers><Trigger Property="IsExpanded" Value="true"><Setter Property="Visibility" TargetName="ExpandSite" Value="Visible" /><Setter Property="Data" TargetName="PathArrow" Value="{StaticResource UpGeometry}" /></Trigger><Trigger Property="IsMouseOver" Value="True" SourceName="BorderHeader"><Setter Property="Visibility" Value="Visible" TargetName="LeftFlag" /><Setter Property="Foreground" Value="White" /></Trigger><Trigger Property="IsExpanded" Value="True"><Setter Property="Visibility" Value="Visible" TargetName="LeftFlag" /><Setter Property="Foreground" Value="White" /></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style><Style x:Key="ListBoxStyle1" TargetType="ListBox"><Setter Property="BorderThickness" Value="0"/><Setter Property="Margin" Value="0"/><Setter Property="Padding" Value="0"/><Setter Property="Background" Value="Red"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="ListBox"><Border  BorderThickness="{TemplateBinding BorderThickness}"><ScrollViewer Margin="{TemplateBinding Padding}"Focusable="false"><StackPanel IsItemsHost="True" /></ScrollViewer></Border></ControlTemplate></Setter.Value></Setter>
</Style><Style x:Key="MenuItemStyle1" TargetType="ListBoxItem"><Setter Property="SnapsToDevicePixels" Value="true"/><Setter Property="FocusVisualStyle" Value="{x:Null}"/><Setter Property="Foreground" Value="LightGray"/><Setter Property="Margin" Value="0"/><Setter Property="Padding" Value="0"/><Setter Property="MinHeight" Value="40"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="ListBoxItem"><Border Name="Border"BorderThickness="0"Padding="40 0 0 0" Background="{Binding MenuItemBackground,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:SideMenuItem}}" SnapsToDevicePixels="True"><ContentPresenter VerticalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsSelected" Value="true"><Setter TargetName="Border" Property="Background" Value="{Binding MenuItemSelectedBackground,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:SideMenuItem}}"/><Setter Property="Foreground" Value="White"/></Trigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Foreground" Value="LightGray"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style><Style TargetType="local:SideMenuItem"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="local:SideMenuItem"><Expander BorderThickness="0"Header="{Binding HeaderText}" IsExpanded="{Binding IsExpanded,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:SideMenuItem}}"Background="{TemplateBinding ToggleBackground}" Style="{StaticResource MenuHeaderStyle1}"><ListBox x:Name="LB"Style="{StaticResource ListBoxStyle1}"ItemsSource="{Binding Items}"ItemContainerStyle="{StaticResource MenuItemStyle1}"></ListBox></Expander></ControlTemplate></Setter.Value></Setter>
</Style>
</ResourceDictionary>

然后在App.xaml里面添加引用:

<Application x:Class="WPFDemos.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WPFDemos"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/WPFDemos;component/Styles/SideMenu.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>
</Application>

最后就是创建一个窗体使用控件喽:

<Window x:Class="WPFDemos.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:WPFDemos"mc:Ignorable="d"x:Name="widnow"UseLayoutRounding="True"Background="LightBlue"Title="下拉菜单控件" Height="450" Width="800"><Grid><StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0 20 0 0"><local:SideMenuItem DataContext="{Binding ItemViewModel}"MenuItemSelectedChanged="S"/><local:SideMenuItem DataContext="{Binding ItemViewModel}"Margin="10 0 0 0"MenuItemBackground="#24ACF2"MenuItemSelectedBackground="YellowGreen"ToggleBackground="#007ACC"MenuItemSelectedChanged="S"/></StackPanel><TextBlock x:Name="log" HorizontalAlignment="Center" FontSize="30" VerticalAlignment="Bottom" Margin="0 0 0 50"/></Grid>
</Window>

窗体的后台代码如下,定义了viewmodel实体和绑定了方法:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WPFDemos
{public partial class MainWindow : Window{public SideMenuItemViewModel ItemViewModel { get; set; }public MainWindow(){ItemViewModel = new SideMenuItemViewModel(){HeaderText = "快速开始",IconGeometry = FindResource("IconInfo") as Geometry,Items = new List<object>(){"5.0新变化","第一个项目","第一个模块","自定义用户","捐赠","FAQ"}};InitializeComponent();DataContext = this;}private void S(object sender, RoutedEventArgs e){var s = e.OriginalSource as ListBox;var str = s.SelectedItem;log.Text = str.ToString();}}
}

这里,视频中演示的效果就实现啦,效果图如下:

结束喽~

如果喜欢,点个赞呗~

-----------------------------------

公众号【Csharp编程大全】,需要进技术群交流的,请添加小编mm1552923!

WPF 制作侧边栏菜单之MenuItem相关推荐

  1. html左侧隐藏菜单栏,如何制作一个炫酷的隐藏侧边栏菜单

    在网上经常可以看到一些效果非常酷的隐藏侧边栏菜单效果.隐藏侧边栏作为一种新的菜单布局方式已经被越来越多的人所接受,它给用户一种全新的体验.特别是在移动手机等小屏幕设备上,隐藏侧边栏就显得特别有用.它不 ...

  2. 菜单侧边栏拖拽_SwiftUI —侧边栏菜单教程

    菜单侧边栏拖拽 This week's SwiftUI tutorial covers a component that I've seen popping up in designs floatin ...

  3. css3+jQuery制作导航菜单(带动画效果)

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>css ...

  4. 好用的侧边栏菜单/面板jQuery插件

    我想大家都用过一些APP应用,它们的菜单展示是以侧边栏滑动方式展现,感觉很新鲜,而现在网页设计也是如此,不少网站也效仿这样的方式来设计.使用侧边栏的好处就是可以节约空间,对于一些内容多或者喜欢简约的网 ...

  5. 【WPF】右键菜单ContextMenu可点击区域太小的问题

    [WPF]右键菜单ContextMenu可点击区域太小的问题 原文:[WPF]右键菜单ContextMenu可点击区域太小的问题 问题描述 正常使用右键菜单ContextMenu时,如果菜单项是不变的 ...

  6. html优美界面左侧下拉,一组时尚的侧边栏菜单和下拉列表UI设计

    这是一款非常时尚的可伸展的侧边栏菜单和select下拉列表以及手风琴式垂直下拉列表UI设计效果.它们通过简单的CSS样式设置,以及和jQuery,jqueryUI的配合,制作出非常时尚的web组件UI ...

  7. VS2019 WPF制作OTA上位机(一)新建工程

    首先创建新项目,文件 -> 新建 -> 项目 下拉菜单选择C#和Window,选择WPF应用程序,下一步 输入项目名,下一步 这里选择.NET 5.0,也可以选择其他的,个人习惯.NET, ...

  8. 每日分享html特效篇1个侧边栏菜单+2个导航栏+1个登录页面+6个加载

    我是c站的一个小博主L_ar,近期我会每天分享前端知识包括(原生的web语句,以及vue2和vue3,微信小程序的写法及知识点)本篇文章收录于html特效专栏中,如果想每天在我这学到一些东西,请关注我 ...

  9. 左侧侧拉栏html,侧边抽屉_纯CSS3抽屉式滑动侧边栏菜单设计

    插件描述:该侧边栏在鼠标滑过菜单项时,会以平滑的方式滑出相应的主菜单,就像拉开抽屉的效果,非常的时尚. 侧边栏菜单设计说明 这是一款使用纯CSS3制作的抽屉式滑动侧边栏菜单设计效果.该侧边栏在鼠标滑过 ...

最新文章

  1. Android之TextView的样式类Span的使用具体解释
  2. SimpleDateFormat处理 dd-MMM-yy类型日期
  3. Java 比较相等 == or .equal()?
  4. 数据结构-编程实现一个单链表的测长
  5. rust(64)-指针类型(1)
  6. Spring框架的前世今生以及对Spring的宏观认识
  7. 【算法系列之十四】最大子序和
  8. 查看和设置tomcat内存
  9. LINUX警告:检测到时钟错误。您的创建可能是不完整的。-转
  10. linux串口驱动支持485,修改2410的linux串口驱动,使其支持RS485
  11. HTML5+CSS3 Pink老师课后作业——小米logo过渡切换的实现
  12. 交换机trunk模式工作原理
  13. #9733;宣传广告变成社会标准
  14. 菜鸟的mongoDB学习---(二)MongoDB 数据库,对象,集合
  15. ubuntu更新过程中出现错误:校验数字签名时出错。此仓库未被更新,下列签名无效
  16. Error: [$injector:unpr] angular.js
  17. 谷粒商城微服务分布式基础篇二—— Spring Cloud Alibaba、Nacos注册与发现
  18. cucumber 如何中途退出 scenario
  19. linux 快速删除大文件夹
  20. Fisher信息量与Cramer-Rao不等式

热门文章

  1. 利用Arcgis地图工具自动输出报告地图图纸
  2. Pandas 替换 NaN 值
  3. 装逼自拍神器Nixie:从手腕上飞起的无人机
  4. 获取select2选中的值_传奇技能第二祭:获取GM权限及管理员命令,调爆率和刷怪...
  5. LibreOJ #6208. 树上询问
  6. Excel表格总是处于只读状态怎么解决?
  7. Flutter学习笔记(二)登陆注册界面的实现
  8. Win11连耳机外放
  9. 应用之星带你玩转H5页面和app开发,不懂技术的看过来
  10. matplotlib绘图的填充