wpf prism左侧抽屉式菜单

文章详细描述了一个使用MaterialDesign风格的WPF应用,涉及左侧菜单的动态显示与隐藏、菜单样式的动画效果、prism框架的Region导航以及C#代码实现。
摘要由CSDN通过智能技术生成

1.首先引入包MaterialDesignColors和MaterialDesignThemes

2.主页面布局

在这里插入图片描述
在这里插入图片描述

左侧菜单显示在窗体外,点击左上角菜单图标通过简单的动画呈现出来

3.左侧窗体外菜单

<Grid x:Name="GridMenu" Width="150" HorizontalAlignment="Left" Margin="-150 0 0 0"  RenderTransformOrigin="0.5,0.5" Background="#4169E1">
    <Grid.RenderTransform>
        <TransformGroup>
            <ScaleTransform/>
            <SkewTransform/>
            <RotateTransform/>
            <TranslateTransform/>
        </TransformGroup>
    </Grid.RenderTransform>
    <StackPanel>
         <Image Source="../Images/head.png"/ Margin="50,20">
        <ListView Foreground="White" FontFamily="Champagne &amp; Limousines" FontSize="18" ItemsSource="{Binding MenuList}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
                        <Button Style="{DynamicResource MenuButtonStyle}"
                            Command="{Binding DataContext.ShowRegionCommand, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"
                            CommandParameter="{Binding ElementName=txtRegion}"/>
                        <TextBlock Text="{Binding Path = RegionName}" Visibility="Collapsed" Name="txtRegion"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
    <Button x:Name="ButtonClose" HorizontalAlignment="Right" VerticalAlignment="Top" Background="{x:Null}" Foreground="White" BorderBrush="{x:Null}" Width="30" Height="30" Padding="0">
        <materialDesign:PackIcon Kind="Close"/>
    </Button>
</Grid>

这里头像的图片写死了,需要的自己替换。

4.菜单样式

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes">
    
    <Storyboard x:Key="CloseMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="GridMenu">
            <EasingDoubleKeyFrame KeyTime="0" Value="150"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="GridBackground">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="ContentGrid">
            <EasingDoubleKeyFrame KeyTime="0" Value="1290"/>
            <!--初始宽度绑定到根Grid的宽度-->
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1440"/>
            <!--减去菜单的宽度-->
        </DoubleAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames  Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ButtonOpen">
            <DiscreteObjectKeyFrame  KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="OpenMenu">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="GridMenu">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="150"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="GridBackground">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="ContentGrid">
            <EasingDoubleKeyFrame KeyTime="0" Value="1440"/>
            <!--初始宽度绑定到根Grid的宽度-->
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1290"/>
            <!--减去菜单的宽度-->
        </DoubleAnimationUsingKeyFrames>

        <ObjectAnimationUsingKeyFrames  Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ButtonOpen">
            <DiscreteObjectKeyFrame  KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Hidden</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>

    <Style TargetType="Button" x:Key="MenuButtonStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border Name="back" BorderThickness="0" Width="130">
                        <StackPanel Orientation="Horizontal" Margin="0">
                            <materialDesign:PackIcon Kind="{Binding Path = Icon}" Width="20" Height="20" Foreground="White" Margin="20,10,0,0" VerticalAlignment="Center"/>
                            <TextBlock Text="{Binding Path = Name}" Margin="10,10,0,0"  Foreground="White" FontFamily="微软雅黑" />
                        </StackPanel>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" Value="Transparent" TargetName="back"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="Transparent" TargetName="back"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

5.主页面事件

<Window.Triggers>
    <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="ButtonClose">
        <BeginStoryboard x:Name="CloseMenu_BeginStoryboard" Storyboard="{StaticResource CloseMenu}"/>
    </EventTrigger>
    <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="ButtonOpen">
        <BeginStoryboard Storyboard="{StaticResource OpenMenu}"/>
    </EventTrigger>
</Window.Triggers>

6.主页面内容

    <Grid x:Name="ContentGrid" HorizontalAlignment="Right" Width="1440">
        <Grid.RowDefinitions>
            <RowDefinition  Height="80"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid Background="#4169E1">
            <Grid x:Name="GridBackground" Background="#55313131" Opacity="0"/>
            <Button x:Name="ButtonOpen" HorizontalAlignment="Left" VerticalAlignment="Top" Background="{x:Null}" BorderBrush="{x:Null}" Width="30" Height="30" Padding="0">
                <materialDesign:PackIcon Kind="Menu" Foreground="#FF313131"/>
            </Button>
            <!--窗体控件按钮-->
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Right">
                <Button Width="40" Height="30" Style="{StaticResource PathButtonStyle}" Foreground="White" Tag="M0 0,10 0" />
                <Button Width="40" Height="30" Style="{StaticResource PathButtonStyle}" Foreground="White" Tag="M0 0,0 10,12 10,12 0Z" />
                <Button Width="50" Height="30" Style="{StaticResource PathButtonStyle}" Foreground="White" Tag="M0 0,12 12M0 12,12 0" />
            </StackPanel>
        </Grid>

        <ContentControl x:Name="Main" prism:RegionManager.RegionName="ContentRegion"  Grid.Row="1"/>

    </Grid>
</Grid>

7.后台C#代码

private readonly IRegionManager _regionManager;
 public MainWindowViewModel(IRegionManager regionManager)
 {
     _regionManager = regionManager;
     ShowRegionCommand = new DelegateCommand<object>(ShowRegion);
     InitMenus();
 }

 private void ShowRegion(object o)
 {
     var text = (o as TextBlock).Text;
     _regionManager.RequestNavigate("ContentRegion", text);
 }

 private ObservableCollection<MenuModel> _menuList;
  public ObservableCollection<MenuModel> MenuList
  {
      get { return _menuList; }
      set
      {
          SetProperty(ref _menuList, value);
      }
  }
private void InitMenus()
{
    MenuList = new ObservableCollection<MenuModel>();
    MenuList.Add(new MenuModel()
    {
        Name = "主页",
        Icon = PackIconKind.Home,
        RegionName = "ContentView"
    });
    MenuList.Add(new MenuModel()
    {
        Name = "测试",
        Icon = PackIconKind.CovidTest,
        RegionName = "TestView"
    });
    MenuList.Add(new MenuModel()
    {
        Name = "设置",
        Icon = PackIconKind.Settings,
        RegionName = "SettingView"
    });
}

RegionName 对应每一个创建Control,具体的规则可以看一下prism的导航。

8.MenuModel类

public class MenuModel
{
    public string Name { get; set; }
    public PackIconKind Icon { get; set; }

    public string RegionName { get; set; }
}

9.prism 导航注册

prism 有个注册类ModuleModule

public class ModuleModule : IModule
{
    private readonly IRegionManager _regionManager;

    public ModuleModule(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }
    /// <summary>
    /// 通知模块已被初始化。
    /// </summary>
    /// <param name="containerProvider"></param>
    public void OnInitialized(IContainerProvider containerProvider)
    {
        _regionManager.RequestNavigate(RegionNames.ContentRegion, "ContentView");
        _regionManager.RequestNavigate(RegionNames.TestRegion, "TestView");
        _regionManager.RequestNavigate(RegionNames.SettingRegion, "SettingView");
    }
    /// <summary>
    /// 用于在您的应用程序将使用的容器中注册类型。
    /// </summary>
    /// <param name="containerRegistry"></param>
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<ContentView>();
        containerRegistry.RegisterForNavigation<TestView>();
        containerRegistry.RegisterForNavigation<SettingView>();
    }
}

然后在App.xaml.cs中注册

 protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
 {
     moduleCatalog.AddModule<ModuleModule>();
 }

10.RegionNames类

public static class RegionNames
{
    public const string TestRegion = "TestRegion";
    public const string SettingRegion = "SettingRegion";
    public const string ContentRegion = "ContentRegion";
}

ContentView 、TestView、SettingView是新建的用户控件,自己随便新建可以区分不同控件查看效果即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨中深巷的油纸伞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值