wpF 实现抽屉菜单
- 框架使用大于等于
.NET40
; Visual Studio 2022
;- 项目使用 MIT 开源许可协议;
- 更多效果可以通过github[1]|码云[2]下载代码;
- 由于在WPF中没有现成的类似UWP的抽屉菜单,所以我们自己实现一个。
1) DrawerMenu.cs 代码如下。
usingSystem.Collections.Generic; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Media; namespaceWPFDevelopers.Controls { publicclassDrawerMenu:ContentControl { publicnewstaticreadonlyDependencyPropertyContentProperty= DependencyProperty.Register("Content",typeof(List<DrawerMenuItem>),typeof(DrawerMenu), newFrameworkPropertyMetadata(null)); publicstaticreadonlyDependencyPropertyIsOpenProperty= DependencyProperty.Register("IsOpen",typeof(bool),typeof(DrawerMenu),newPropertyMetadata(true)); publicstaticreadonlyDependencyPropertyMenuIconColorProperty= DependencyProperty.Register("MenuIconColor",typeof(Brush),typeof(DrawerMenu), newPropertyMetadata(Brushes.White)); publicstaticreadonlyDependencyPropertySelectionIndicatorColorProperty= DependencyProperty.Register("SelectionIndicatorColor",typeof(Brush),typeof(DrawerMenu), newPropertyMetadata(DrawingContextHelper.Brush)); publicstaticreadonlyDependencyPropertyMenuItemForegroundProperty= DependencyProperty.Register("MenuItemForeground",typeof(Brush),typeof(DrawerMenu), newPropertyMetadata(Brushes.Transparent)); staticDrawerMenu() { DefaultStyleKeyProperty.OverrideMetadata(typeof(DrawerMenu), newFrameworkPropertyMetadata(typeof(DrawerMenu))); } publicnewList<DrawerMenuItem>Content { get=>(List<DrawerMenuItem>)GetValue(ContentProperty); set=>SetValue(ContentProperty,value); } publicboolIsOpen { get=>(bool)GetValue(IsOpenProfIlLJrperty); set=>SetValue(IsOpenProperty,value); } publicBrushMenuIconColor { get=>(Brush)GetValue(MenuIconColorProperty); set=>SetValue(MenuIconColorProperty,value); } publicBrushSelectionIndicatorColor { get=>(Brush)GetValue(SelectionIndicatorColorProperty); set=>SetValue(SelectionIndicatorColorProperty,value); } publicBrushMenuItemForeground { get=>(Brush)GetValue(MenuItemForegroundProperty); set=>SetValue(MenuItemForegroundProperty,value); } publicoverridevoidBeginInit() { Content=newList<DrawerMenuItem>(); base.BeginInit(); } } }
2) DrawerMenuItem.cs 代码如下。
usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Input; usingSystem.Windows.Media; namespaceWPFDevelopers.Controls { publicclassDrawerMenuItem:ListBoxItem { publicstaticreadonlyDependencyPropertyTextProperty= DependencyProperty.Register("Text",typeof(string),typeof(DrawerMenuItem), newPropertyMetadata(string.Empty)); publicstaticreadonlyDependencyPropertyIconProperty= DependencyProperty.Register("Icon",typeof(ImageSource),typeof(DrawerMenuItem), newPropertyMetadata(null)); publicstaticreadonlyDependencyPropertySelectionIndicatorColorProperty= DependencyProperty.Register("SelectionIndicatorColor",typeof(Brush),typeof(DrawerMenuItem), newPropertyMetadata(DrawingContextHelper.Brush)); publicstaticreadonlyDependencyPropertySelectionCommandProperty= DependencyProperty.Register("SelectionCommand",typeof(ICommand),typeof(DrawerMenuItem), newPropertyMetadata(null)); staticDrawerMenuItem() { DefaultStyleKeyProperty.OverrideMetadata(typeof(DrawerMenuItem), newFrameworkPropertyMetadata(typeof(DrawerMenuItem))); } publicstringText { get=>(string)GetValue(TextProperty); set=>SetValue(TextProperty,value); } publicImageSourceIcon { get=>(ImageSource)GetValue(IconProperty); set=>SetValue(IconProperty,value); } publicBrushSelectionIndicatorColor { get=>(Brush)GetValue(SelectionIndicatorColorProperty); set=>SetValue(SelectionIndicatorColorProperty,value); } publicICommandSelectionCommand { get=>(ICommand)GetValue(SelectionCommandProperty); set=>SetValue(SelectionCommandProperty,value); } } }
3) DrawerMenu.xaml 代码如下。
<ResourceDictionaryXMLns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" xmlns:controls="clr-namespace:WPFDevelopers.Controls"> <ResourceDictionary.MergedDictionaries> <ResourceDictionarySource="Basic/ControlBasic.xaml"/> </ResourceDictionary.MergedDictionaries> <Stylex:Key="DrawerMenuToggleButton"TargetType="ToggleButton"BasedOn="{StaticResourceControlBasicStyle}"> <SetterProperty="IsChecked"Value="False"/> <SetterProperty="Template"> <Setter.Value> <ControlTemplateTargetType="{x:TypeToggleButton}"> <GridBackground="{TemplateBindingBackground}"> <ContentPresenterHorizontalAlignment="Center"VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <TriggerProperty="IsMouseover"Value="True"> <SetterProperty="Opacity"Value="0.8"/> <SetterProperty="Cursor"Value="Hand"/> <SetterProperty="Template"> <Setter.Value> <ControlTemplateTargetType="{x:TypeToggleButton}"> <Border Background="{TemplateBindingBackground}" BorderBrush="Black" BorderThickness="1"> <ContentPresenterHorizontalAlignment="Center"VerticalAlignment="Center"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> <Stylex:Key="DrawerMenuListBox"TargetType="ListBox"BasedOn="{StaticResourceControlBasicStyle}"> <SetterProperty="Background"Value="Transparent"/> <SetterProperty="BorderBrush"Value="Transparent"/> <SetterProperty="BorderThickness"Value="0"/> <SetterProperty="Template"> <Setter.Value> <ControlTemplate> <ScrollViewer> <ItemsPresenterMargin="0"/> </ScrollViewer> </ControlTemplate> </Setter.Value> </Setter> </Style> <Stylex:Key="ButtonFocusVisual"> <SetterProperty="Control.Template"> <Setter.Value> <ControlTemplate> <Border> <Rectangle Margin="2" StrokeThickness="1" Stroke="#60000000" StrokeDashArray="12"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--FillBrushes--> <SolidColorBrushx:Key="NormalBrush"Color="Transparent"po:Freeze="True"/> <SolidColorBrushx:Key="DarkBrush"Color="#ddd"po:Freeze="True"/> <SolidColorBrushx:Key="PressedBrush"Color="#80FFFFFF"po:Freeze="True"/> <SolidColorBrushx:Key="www.devze.comDisabledForegroundBrush"Color="Transparent"po:Freeze="True"/> <SolidColorBrushx:Key="DisabledBackgroundBrush"Color="Transparent"po:Freeze="True"/> <!--BorderBrushes--> <SolidColorBrushx:Key="NormalBorderBrush"Color="Transparent"po:Freeze="True"/> <SolidColorBrushx:Key="PressedBorderBrush"Color="Transparent"po:Freeze="True"/> <SolidColorBrushx:Key="DefaultedBorderBrush"Color="Transparent"po:Freeze="True"/> <SolidColorBrushx:Key="DisabledBorderBrush"Color="Transparent"po:Freeze="True"/> <Stylex:Key="DrawerMenuItemButtonStyle"TargetType="Button"BasedOn="{StaticResourceControlBasicStyle}"> <SetterProperty="FocusVisualStyle"Value="{StaticResourceButtonFocusVisual}"/> <SetterProperty="MinHeight"Value="23"/> <SetterProperty="MinWidth"Value开发者_Js入门="75"/> <SetterProperty="Cursor"Value="Hand"/> <SetterProperty="Template"> <Setter.Value> <ControlTemplateTargetType="Button"> <Border x:Name="Border" CornerRadius="0" BorderThickness="0" Background="Transparent" BorderBrush="Transparent"> <ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RecognizesAccessKey="True"/> </Border> <ControlTemplate.Triggers> <TriggerProperty="IsKeyboardFocused"Value="true"> <SetterTargetName="Border"Property="BorderBrush"Value="{DynamicResourceDefjavascriptaulted编程客栈BorderBrush}"/> </Trigger> <TriggerProperty="IsDefaulted"Value="true"> <SetterTargetName="Border"Property="BorderBrush"Value="{DynamicResourceDefaultedBorderBrush}"/> </Trigger> <TriggerProperty="IsMouseOver"Value="true"> <SetterTargetName="Border"Property="Background"Value="{DynamicResourceDarkBrush}"/> </Trigger> <TriggerProperty="IsPressed"Value="true"> <SetterTargetName="Border"Property="Background"Value="{DynamicResourcePressedBrush}"/> <SetterTargetName="Border"Property="BorderBrush"Value="{DynamicResourcePressedBorderBrush}"/> </Trigger> <TriggerProperty="IsEnabled"Value="false"> <SetterTargetName="Border"Property="Background"Value="{DynamicResourceDisabledBackgroundBrush}"/> <SetterTargetName="Border"Property="BorderBrush"Value="{DynamicResourceDisabledBorderBrush}"/> <SetterProperty="Foreground"Value="{DynamicResourceDisabledForegroundBrush}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <StyleTargetType="controls:DrawerMenuItem"> <SetterProperty="HorizontalContentAlignment"Value="Stretch"/> <SetterProperty="Foreground"Value="{BindingRelativeSource={RelativeSourceAncestorType={x:Typecontrols:DrawerMenu}},Path=MenuItemForeground}"/> <SetterProperty="SelectionIndicatorColor"Value="{BindingRelativeSource={RelativeSourceAncestorType={x:Typecontrols:DrawerMenu}},Path=SelectionIndicatorColor}"/> <SetterProperty="Template"> <Setter.Value> <ControlTemplateTargetType="controls:DrawerMenuItem"> <Buttonx:Name="PART_Button"Height="44" Command="{TemplateBindingSelectionCommand}" ToolTip="{TemplateBindingText}" HorizontalContentAlignment="Stretch"VerticalContentAlignment="Stretch" Style="{StaticResourceDrawerMenuItemButtonStyle}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinitionWidth="5"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <GridGrid.ColumnSpan="2"> <Gridwidth="300"> <Grid.ColumnDefinitions> <ColumnDefinitionWidth="45"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ImageGrid.Column="0"Source="{TemplateBindingIcon}"Margin="10,5,5,5"/> <TextblockText="{TemplateBindingText}"Grid.Column="1" Margin="10,0,0,0"HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="{StaticResourceTitleFontSize}" Foreground="{TemplateBindingForeground}" TextWrapping="Wrap"/> </Grid> </Grid> <GridName="PART_ItemSelectedIndicator" Grid.Column="0" Background="{TemplateBindingSelectionIndicatorColor}" Visibility="Collapsed"/> </Grid> </Button> <Controwww.devze.comlTemplate.Triggers> <TriggerProperty="IsSelected"Value="True"> <SetterTargetName="PART_ItemSelectedIndicator"Property="Visibility"Value="Visible"/> </Trigger> <TriggerSourceName="PART_Button"Property="IsPressed"Value="True"> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <BooleanAnimationUsingKeyFramesStoryboard.TargetProperty="IsSelected"> <DiscreteBooleanKeyFrameKeyTime="00:00:00"Value="True"/> </BooleanAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <StyleTargetType="controls:DrawerMenu"> <SetterProperty="Width"Value="50"/> <SetterProperty="Visibility"Value="Visible"/> <SetterProperty="IsOpen"Value="True"/> <SetterProperty="Template"> <Setter.Value> <ControlTemplateTargetType="controls:DrawerMenu"> <GridBackground="{TemplateBindingBackground}"> <ToggleButtonHorizontalAlignment="Left"Background="#333" VerticalAlignment="Top"Height="40"Width="50" IsChecked="{BindingRelativeSource={RelativeSourceAncestorType={x:Typecontrols:DrawerMenu}},Path=IsOpen}" Style="{StaticResourceDrawerMenuToggleButton}"> <PathHorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Uniform"Width="20" Fill="{TemplateBindingMenuIconColor}" Data="{StaticResourcePathMenu}"/> </ToggleButton> <ListBoxItemsSource="{TemplateBindingContent}" HorizontalAlignment="Left"Margin="0,40,0,0" VerticalAlignment="Top" Style="{StaticResourceDrawerMenuListBox}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedIndex="0"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <TriggerProperty="IsOpen"Value="False"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="Width" To="180" Duration="0:0:0.2"/> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="Width" To="50" Duration="0:0:0.2"/> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </Style.Triggers> </Style> </ResourceDictionary>
4) DrawerMenuExample.xaml 代码如下。
<UserControlx:Class="WPFDevelopers.Samples.ExampleViews.DrawerMenu.DrawerMenuExample" 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:WPFDevelopers.Samples.ExampleViews.DrawerMenu" xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers" mc:Ignorable="d" d:DesignHeight="450"d:DesignWidth="800"> <GridBackground="#FF7B7BFF"> <Grid.ColumnDefinitions> <ColumnDefinitionWidth="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <wpfdev:DrawerMenuBackground="#eee" SelectionIndicatorColor="{StaticResourcePrimaryPressedSolidColorBrush}" MenuItemForeground="{StaticResourceBlackSolidColorBrush}"HorizontalAlignment="Left"> <wpfdev:DrawerMenu.Content> <wpfdev:DrawerMenuItemIcon="pack://application:,,,/Images/CircularMenu/2.png"Text="主页" SelectionCommand="{BindingHomeCommand,RelativeSource={RelativeSourceAncestorType=local:DrawerMenuExample}}"/> <wpfdev:DrawerMenuItemIcon="pack://application:,,,/Images/CircularMenu/4.png"Text="Edge" SelectionCommand="{BindingEdgeCommand,RelativeSource={RelativeSourceAncestorType=local:DrawerMenuExample}}"/> <wpfdev:DrawerMenuItemIcon="pack://application:,,,/Images/CircularMenu/1.png"Text="云盘" SelectionCommand="{BindingCloudCommand,RelativeSource={RelativeSourceAncestorType=local:DrawerMenuExample}}"/> <wpfdev:DrawerMenuItemIcon="pack://application:,,,/Images/CircularMenu/8.png"Text="邮件" SelectionCommand="{BindingMailCommand,RelativeSource={RelativeSourceAncestorType=local:DrawerMenuExample}}"/> <wpfdev:DrawerMenuItemIcon="pack://application:,,,/Images/CircularMenu/6.png"Text="视频" SelectionCommand="{BindingVideoCommand,RelativeSource={RelativeSourceAncestorType=local:DrawerMenuExample}}"/> </wpfdev:DrawerMenu.Content> </wpfdev:DrawerMenu> <FrameName="myFrame"Grid.Column="1"Margin="0,40,0,0" NavigationUIVisibility="Hidden"></Frame> </Grid> </UserControl>
5) DrawerMenuExample.xaml.cs 代码如下。
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Windows; usingSystem.Windows.Controls; usingSystem.Windows.Input; usingSystem.Windows.Media; usingWPFDevelopers.Samples.Helpers; namespaceWPFDevelopers.Samples.ExampleViews.DrawerMenu { ///<summary> ///Win10MenuExample.xaml的交互逻辑 ///</summary> publicpartialclassDrawerMenuExample:UserControl { privateList<Uri>_uriList=newList<Uri>() { newUri("ExampleViews/DrawerMenu/HomePage.xaml",UriKind.Relative), newUri("ExampleViews/DrawerMenu/EdgePage.xaml",UriKind.Relative), }; publicDrawerMenuExample() { InitializeComponent(); myFrame.Navigate(_uriList[0]); } publicICommandHomeCommand=>newRelayCommand(obj=> { myFrame.Navigate(_uriList[0]); }); publicICommandEdgeCommand=>newRelayCommand(obj=> { myFrame.Navigate(_uriList[1]); }); publicICommandCloudCommand=>newRelayCommand(obj=> { WPFDevelopers.Minimal.Controls.MessageBox.Show("点击了云盘","提示"); }); publicICommandMailCommand=>newRelayCommand(obj=> { WPFDevelopers.Minimal.Controls.MessageBox.Show("点击了邮件","提示"); }); publicICommandVideoCommand=>newRelayCommand(obj=> { WPFDevelopers.Minimal.Controls.MessageBox.Show("点击了视频","提示"); }); } }
6) HomePage.xaml.cs 代码如下。
<Pagex:Class="WPFDevelopers.Samples.ExampleViews.DrawerMenu.HomePage" 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:WPFDevelopers.Samples.ExampleViews.DrawerMenu" mc:Ignorable="d" d:DesignHeight="450"d:DesignWidth="800" Title="HomePage"Background="{StaticResourcePrimaryTextSolidColorBrush}"> <Grid> <TextBlockVerticalAlignment="Center" HorizontalAlignment="Center" Width="400"TextAlignment="Center" TextWrapping="Wrap" Margin="0,0,0,40" FontSize="{StaticResourceNormalFontSize}"> <RunForeground="White">Home</Run> <RunText="微信公众号WPFDevelopers"FontSize="40" Foreground="#A9CC32"FontWeight="Bold"></Run> <LineBreak/> <HyperlinkNavigateUri="https://github.com/WPFDevelopersOrg/WPFDevelopers.git" RequestNavigate="GithubHyperlink_RequestNavigate">Github源代码</Hyperlink> <Run/> <Run/> <Run/> <HyperlinkNavigateUri="https://gitee.com/yanjinhua/WPFDevelopers.git" RequestNavigate="GiteeHyperlink_RequestNavigate">码云源代码</Hyperlink> </TextBlock> </Grid> </Page>
7) EdgePage.xaml.cs 代码如下。
<Pagex:Class="WPFDevelopers.Samples.ExampleViews.DrawerMenu.EdgePage" 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:WPFDevelopers.Samples.ExampleViews.DrawerMenu" mc:Ignorable="d" d:DesignHeight="450"d:DesignWidth="800" Title="EdgePage"Background="{DynamicResourcePrimaryPressedSolidColorBrush}"> <Grid> <StackPanelVerticalAlignment="Center" Margin="0,0,0,40"> <ImageSource="pack://application:,,,/Images/CircularMenu/4.png"Stretch="Uniform" Width="50"/> <TextBlockVerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" Foreground="White" Text="即将跳转至Edge浏览器" FontSize="{StaticResourceTitleFontSize}" Padding="0,10"> </TextBlock> </StackPanel> </Grid> </Page>
效果图
到此这篇关于WPF实现抽屉菜单效果的示例代码的文章就介绍到这了,更多相关WPF抽屉菜单内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
精彩评论