WPF实现半圆形导航菜单
作者:RunnerDNA 发布时间:2023-06-09 07:02:56
标签:WPF,导航,菜单
本文实例为大家分享了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));
}
来源:https://blog.csdn.net/dnazhd/article/details/108061673


猜你喜欢
- LRU缓存替换策略缓存是一种非常常见的设计,通过将数据缓存到访问速度更快的存储设备中,来提高数据的访问速度,如内存、CPU缓存、硬盘缓存等。
- 前言在开发中我们经常要使用图片或者drawable文件夹下的xml,来实现一些效果,Drawable的用法都和xml相关,我们可以使用sha
- WPF的ImageBrush是一个比较常见也比较复杂的笔刷,它继承自图块笔刷(TileBrush)。使用图块画笔绘制区域涉及以下三个组成部分
- 使用zxing批量在做好的立牌背景图的指定位置上,把指定的文本内容(链接地址、文本等)生成二维码并放在该位置,最后加上立牌编号。步骤:1).
- java 多线程的几种实现方法总结1.多线程有几种实现方法?同步有几种实现方法?多线程有两种实现方法,分别是继承Thread类与实现Runn
- 当键盘敲下后退键(Backspace)后1、禁止浏览器自动后退2、但不影响密码、单行文本、多行文本输入框等的回退操作<script t
- 直接插入排序直接插入排序的思路很容易理解,它是这样的:1.把待排序的数组分成已排序和未排序两部分,初始的时候把第一个元素认为是已排好序的。2
- 目录1.项目需求描述2.整体思路3.功能实现1.项目需求描述通过订单号获取某系统内订单的详细数据,不需要账号密码的登录验证,但有图片验证码的
- 前言可能有人会有疑问,为什么外面已经有更好的组件,为什么还要重复的造轮子,只能说,别人的永远是别人的,自己不去造一下,就只能知其然,而不知其
- 一、顺序结构程序的执行和代码的执行顺序有关,如果调整代码的书写顺序, 则执行顺序也发生变化二、分支结构基本语法形式1:if(布尔表达式){
- 类加载是什么把磁盘中的java文件加载到内存中的过程叫做类加载当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把
- 服务端在平台上创建springboot小程序应用创建小程序登录蚂蚁金服开放平台,扫码登录填写信息后,点击支付宝小程序,选择立即接入 >
- 概述:利用AccessibilityService机制实现了一个比较好玩儿的功能,微信朋友圈自动遍历点赞。即通过不断的滚动+点赞实现把每一条
- 一、Spring-boot配置mybatis的mapper-locations解决什么问题?mapper-locations顾名思义是一个定
- 本文实例为大家分享了Java网络编程TCP实现文件上传的具体代码,供大家参考,具体内容如下上一篇博客,用网络编程TCP 实现聊天,这次实现文
- 前言在做项目的时候,遇到一个需求,需要我对Chart图标标记数据正在运行,实现数据可视化,因为我们的表格是隐藏Y轴的刻度是看不到数据值的,于
- 使用工具:IDEA2022Tomcat9.0.41.下载Tomcat:官网:https://tomcat.apache.org/找到需要的版
- 什么是委托?委托是寻址方法的.NET版本,使用委托可以将方法作为参数进行传递。委托是一种特殊类型的对象,其特殊之处在于委托中包含的只是一个活
- 可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了。
- Java 匿名内部类详解匿名内部类也就是没有名字的内部类正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写但使用