开发者

WPF实现抽屉菜单效果的示例代码

开发者 https://www.devze.com 2022-12-01 12:43 出处:网络 作者: 驚鏵
WPF实现抽屉菜单框架使用大于等于.NET40;VisualStudio2022;项目使用MIT开源许可协议;更多效果可以通过GitHub[1]|码云[2]下载代码;由于在WPF中没有现成的类似...

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实现抽屉菜单效果的示例代码的文章就介绍到这了,更多相关WPF抽屉菜单内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号