WPF实现半圆形导航菜单

所属分类: 软件编程 / C#教程 阅读数: 355
收藏 0 赞 0 分享

本文实例为大家分享了WPF实现半圆形导航菜单的具体代码,供大家参考,具体内容如下

实现效果如下:

思路:

扇形自定义控件组合成半圆型菜单,再通过clip实现菜单的展开和折叠。

步骤:

1、扇形自定义控件CircularSectorControl

窗体布局xaml:

<Grid x:Name="mainGrid" MouseEnter="MainGrid_MouseEnter" MouseLeave="MainGrid_MouseLeave">
    <Path x:Name="sectorPath" Data="M 200,200 0,200 A 200,200 0 0 1 58.6,58.6z" Fill="{Binding ElementName=sector, Path=BackgroundColor}"></Path>
    <Image Source="{Binding ElementName=sector, Path=DisplayImage}" Stretch="Fill" Width="35" Height="35" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="40,10">
      <Image.RenderTransform>
        <RotateTransform Angle="-67.5"></RotateTransform>
      </Image.RenderTransform>
    </Image>
</Grid>

交互逻辑:

public static readonly DependencyProperty DisplayImageProperty = DependencyProperty.Register("DisplayImage", typeof(ImageSource), typeof(CircularSectorControl), new PropertyMetadata(null));
 public ImageSource DisplayImage
    {
      get { return (ImageSource)GetValue(DisplayImageProperty); }
      set { SetValue(DisplayImageProperty, value); }
    }
 
    public static readonly DependencyProperty BackgroundColorProperty = DependencyProperty.Register("BackgroundColor", typeof(SolidColorBrush), typeof(CircularSectorControl), new PropertyMetadata(null));
    public SolidColorBrush BackgroundColor
    {
      get { return (SolidColorBrush)GetValue(BackgroundColorProperty); }
      set { SetValue(BackgroundColorProperty, value); }
    }
 
    public CircularSectorControl()
    {
      InitializeComponent();
    }
 
    private void MainGrid_MouseEnter(object sender, MouseEventArgs e)
    {
      this.sectorPath.Fill = new SolidColorBrush(Color.FromRgb(246,111,111));
    }
 
    private void MainGrid_MouseLeave(object sender, MouseEventArgs e)
    {
      this.sectorPath.Fill = BackgroundColor;
}

2、半圆型菜单控件

窗体布局xaml:

<UserControl.Resources>
    <Storyboard x:Key="stbShow">
      <DoubleAnimation Storyboard.TargetName="myEllipseGeometry"
               Storyboard.TargetProperty="RadiusX"
               Duration="0:0:0.5" From="0" To="200"
               FillBehavior="HoldEnd"/>
      <DoubleAnimation Storyboard.TargetName="myEllipseGeometry"
               Storyboard.TargetProperty="RadiusY"
               Duration="0:0:0.5" From="0" To="200"
               FillBehavior="HoldEnd" />
    </Storyboard>
    <Storyboard x:Key="stbHide">
      <DoubleAnimation Storyboard.TargetName="myEllipseGeometry"
               Storyboard.TargetProperty="RadiusX"
               Duration="0:0:0.5" From="200" To="0"
               FillBehavior="HoldEnd"/>
      <DoubleAnimation Storyboard.TargetName="myEllipseGeometry"
               Storyboard.TargetProperty="RadiusY"
               Duration="0:0:0.5" From="200" To="0"
               FillBehavior="HoldEnd" />
    </Storyboard>
  </UserControl.Resources>
  <Canvas x:Name="mainCanvas" Cursor="Hand" ClipToBounds="True">
    <Canvas x:Name="sectorCanvas">
      <local:CircularSectorControl BackgroundColor="#F44E4E" DisplayImage="Images/1.png"></local:CircularSectorControl>
      <local:CircularSectorControl BackgroundColor="#F45757" DisplayImage="Images/2.png">
        <local:CircularSectorControl.RenderTransform>
          <RotateTransform Angle="45" CenterX="200" CenterY="200"></RotateTransform>
        </local:CircularSectorControl.RenderTransform>
      </local:CircularSectorControl>
      <local:CircularSectorControl BackgroundColor="#F44E4E" DisplayImage="Images/3.png">
        <local:CircularSectorControl.RenderTransform>
          <RotateTransform Angle="90" CenterX="200" CenterY="200"></RotateTransform>
        </local:CircularSectorControl.RenderTransform>
      </local:CircularSectorControl>
      <local:CircularSectorControl BackgroundColor="#F45757" DisplayImage="Images/4.png">
        <local:CircularSectorControl.RenderTransform>
          <RotateTransform Angle="135" CenterX="200" CenterY="200"></RotateTransform>
        </local:CircularSectorControl.RenderTransform>
      </local:CircularSectorControl>
    </Canvas>
    <Path>
      <Path.Data>
        <EllipseGeometry x:Name="myEllipseGeometry" RadiusX="0" RadiusY="0" Center="200,200"></EllipseGeometry>
      </Path.Data>
    </Path>
    <Grid x:Name="bottomGrid" Canvas.Left="150" Canvas.Top="150" MouseLeftButtonDown="BottomGrid_MouseLeftButtonDown">
      <Path Data="M 0,0 A 100,100 1 0 1 200,0z" Fill="White" Stretch="Fill" Width="100" Height="50"/>
      <TextBlock x:Name="bottomTB" Text="+" FontSize="38" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
    </Grid>
</Canvas>

交互逻辑:

//委托
public delegate void EventHandle(bool isShow);
public event EventHandle ShowClickEvent;
 
 private Storyboard storyboard = new Storyboard();
 
    public RoundMenuControl()
    {
      InitializeComponent();
      CompositionTarget.Rendering += UpdateEllipse;
    }
 
    private void UpdateEllipse(object sender, EventArgs e)
    {
      this.sectorCanvas.Clip = this.myEllipseGeometry;
    }
 
    private void BottomGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    { 
      if (this.bottomTB.Text == "+")
      {
        this.bottomTB.Text = "-";
        Storyboard stbShow = (Storyboard)FindResource("stbShow");
        stbShow.Begin();
        ShowClickEvent?.Invoke(true);
      }
      else
      {
        this.bottomTB.Text = "+";
        Storyboard stbHide = (Storyboard)FindResource("stbHide");
        stbHide.Begin();
        ShowClickEvent?.Invoke(false);
      }
}

3、主窗体调用

窗体布局xaml:

<Window x:Class="RoundMenu.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:RoundMenu"
    Title="MainWindow" Width="650" Height="400" Background="#f6c06d" WindowStartupLocation="CenterScreen">
  <Grid>
    <local:RoundMenuControl x:Name="roundMenu" Margin="125,170,100,0"></local:RoundMenuControl>
  </Grid>
</Window>

交互逻辑:

public MainWindow()
 {
  InitializeComponent();
    this.roundMenu.ShowClickEvent += RoundMenu_ShowClickEvent;
  }
 
  private void RoundMenu_ShowClickEvent(bool isShow)
    {
      if (isShow)
        this.Background = new SolidColorBrush(Color.FromRgb(255, 128, 79));
      else
        this.Background = new SolidColorBrush(Color.FromRgb(246, 192, 109));
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

c#开发word批量转pdf源码分享

已经安装有Office环境,借助一些简单的代码即可实现批量Word转PDF,看下面的实例源码吧
收藏 0 赞 0 分享

c# xml API操作的小例子

这篇文章主要介绍了c# xml API操作的小例子,有需要的朋友可以参考一下
收藏 0 赞 0 分享

c#唯一值渲染实例代码

这篇文章主要介绍了c#唯一值渲染实例代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

淘宝IP地址库采集器c#代码

这篇文章主要介绍了淘宝IP地址库采集器c#代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C#在后台运行操作(BackgroundWorker用法)示例分享

BackgroundWorker类允许在单独的专用线程上运行操作。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题,下面看示例
收藏 0 赞 0 分享

c#文本加密程序代码示例

这是一个加密软件,但只限于文本加密,加了窗口控件的滑动效果,详细看下面的代码
收藏 0 赞 0 分享

c#生成站点地图(SiteMapPath)文件示例程序

这篇文章主要介绍了c#生成站点地图(SiteMapPath)文件的示例,大家参考使用
收藏 0 赞 0 分享

C# 键盘Enter键取代Tab键实现代码

这篇文章主要介绍了C# 键盘Enter键取代Tab键实现代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C# WinForm导出Excel方法介绍

在.NET应用中,导出Excel是很常见的需求,导出Excel报表大致有以下三种方式:Office PIA,文件流和NPOI开源库,本文只介绍前两种方式
收藏 0 赞 0 分享

C#串口通信程序实例详解

在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports,创建C#串口通信程序的具体实现是如何的呢?让我们开始吧
收藏 0 赞 0 分享
查看更多