首页 > 其他分享 >WPF椭圆弧形弧线控件

WPF椭圆弧形弧线控件

时间:2023-10-11 16:25:36浏览次数:54  
标签:控件 return 弧线 double FrameworkPropertyMetadataOptions new WPF Math size

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfApp2.Controls
{
    public class Arc : Shape
    {
        Size _size = Size.Empty;
        protected override Geometry DefiningGeometry {
            get
            {
                if(_size == Size.Empty)
                    return Geometry.Empty;
                return GetGeometry();
            }
        }

        Geometry GetGeometry()
        {
            double angle = this.EndAngle - StartAngle;
            if (angle == 0) return Geometry.Empty;
            if (Math.Abs(angle) >= 360d) return new EllipseGeometry(new Point(_size.Width / 2, _size.Height / 2), RadiusXNoThickness, RadiusYNoThickness);

            var path = new PathGeometry();
            var figure = new PathFigure();
            path.Figures.Add(figure);
            var arc = new ArcSegment();
            figure.Segments.Add(arc);

            arc.IsLargeArc = Math.Abs(EndAngle) > 180 || Math.Abs(EndAngle - StartAngle) > 180;
            arc.SweepDirection = EndAngle > StartAngle ? SweepDirection.Counterclockwise : SweepDirection.Clockwise;
            arc.Size = new Size(RadiusXNoThickness, RadiusYNoThickness);
            arc.Point = GetPoint(EndAngle);
            figure.StartPoint = GetPoint(StartAngle);
            if (IsStartCenter)
            {
                figure.Segments.Insert(0, new LineSegment(figure.StartPoint, true));
                figure.StartPoint = new Point(_size.Width / 2, _size.Height / 2);
            }
            if(IsClosed)
                figure.IsClosed = true;
            return path;
        }

        Point GetPoint(double angle)
        {
            double d = angle / 180 * Math.PI;
            double a = RadiusXNoThickness, b = RadiusYNoThickness;
            double t = a * b / Math.Sqrt(Math.Pow(a * Math.Sin(d), 2) + Math.Pow(b * Math.Cos(d), 2));
            double x = t * Math.Cos(d);
            double y = t * Math.Sin(d);
            var endPoint = new Point(x + a + (StrokeThickness / 2), b - y + (StrokeThickness / 2));
            return endPoint;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            _size = constraint;
            return base.MeasureOverride(constraint);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _size = finalSize;
            return base.ArrangeOverride(finalSize);
        }

        double RadiusXNoThickness => Math.Max(_size.Width / 2 - StrokeThickness / 2, 0);
        double RadiusYNoThickness => Math.Max(_size.Height / 2 - StrokeThickness / 2, 0);

        /// <summary>
        /// 起始点角度
        /// </summary>
        public double StartAngle
        {
            get { return (double)GetValue(StartAngleProperty); }
            set { SetValue(StartAngleProperty, value); }
        }

        public static readonly DependencyProperty StartAngleProperty =
            DependencyProperty.Register("StartAngle", typeof(double), typeof(Arc), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender));

        /// <summary>
        /// 终点角度
        /// </summary>
        public double EndAngle
        {
            get { return (double)GetValue(EndAngleProperty); }
            set { SetValue(EndAngleProperty, value); }
        }

        public static readonly DependencyProperty EndAngleProperty =
            DependencyProperty.Register("EndAngle", typeof(double), typeof(Arc), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender));

        /// <summary>
        /// 是否从椭圆中心开始画线
        /// </summary>
        public bool IsStartCenter
        {
            get { return (bool)GetValue(IsStartCenterProperty); }
            set { SetValue(IsStartCenterProperty, value); }
        }

        public static readonly DependencyProperty IsStartCenterProperty =
            DependencyProperty.Register("IsStartCenter", typeof(bool), typeof(Arc), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender));

        /// <summary>
        /// 是否封闭图形
        /// </summary>
        public bool IsClosed
        {
            get { return (bool)GetValue(IsClosedProperty); }
            set { SetValue(IsClosedProperty, value); }
        }

        public static readonly DependencyProperty IsClosedProperty =
            DependencyProperty.Register("IsClosed", typeof(bool), typeof(Arc), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsRender));
    }
}
View Code

 

属性:

StartAngle: 起点角度;

EndAngle: 终点角度;

IsStartCenter:是否从圆心开始画线;

IsClosed:是否封闭;

使用方式:

<control:Arc Width="100" Height="100" StartAngle="110" EndAngle="-45" Stroke="Blue" StrokeThickness="5" IsStartCenter="True" IsClosed="True" Fill="Orange"/>

 

标签:控件,return,弧线,double,FrameworkPropertyMetadataOptions,new,WPF,Math,size
From: https://www.cnblogs.com/RedSky/p/17757458.html

相关文章

  • element 的 el-cascader 控件,去掉空子集
    后端返回的树结构数据: template:<el-cascaderv-model="ruleForm.columnAll":options="allColumnData":props="{value:'columnId',label:'columnName',children:'children'}"/> methods://获取......
  • winform-RichTextBox控件(有格式文本控件)
    RichTextBox控件用于显示、输入和操作带有格式的文本   除了执行TextBox控件的所有功能外,还可以显示字体、颜色和链接 1、在RichTextBox控件中显示滚动条  2、在RichTextBox控件中设置字体属性 3、将RichTextBox控件显示为超链接样式 4、在RichTextBox控件......
  • 界面组件DevExpress WPF v23.1 - 进一步升级数据处理能力
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为中心......
  • dotnet 8 WPF 支持在 RDP 远程桌面状态下启用渲染硬件加速
    本文将和大家介绍在dotnet8里WPF引入的新功能之一,在RDP远程桌面状态下启用渲染硬件加速在dotnet8之前,在用户进行RDP远程桌面时WPF应用将默认关闭硬件渲染加速以获得更好的兼容性。随着系统层的渲染架构的优化,比如在WDDM驱动模型里面,进行远程桌面的硬件加速已经是......
  • 虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序
    虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件,可以内置到任何WPF应用程序虚拟桌宠模拟器一个开源的桌宠软件,可以内置到任何WPF应用程序获取虚拟桌宠模拟器OnSteam(免费)或通过Nuget内置到你的WPF应用程序1.虚拟桌宠模拟器详细介绍虚拟桌宠模拟器是一款桌宠软件,......
  • Winform-Button控件
    1、响应按钮的单击事件2、将按钮设置为窗体的“接受”按钮--就是按enter默认单击3、将按钮设置为窗体的“取消”按钮 ......
  • winform-Windows控件概述
    控件分类:文本类控件、选择类控件、分组控件、菜单控件、工具栏控件、状态栏控件控件命名规范:         控件的相关操作添加控件1、在窗口上绘制控件2、将控件拖拽到窗体上3、以编程的方式向窗体添加控件      ......
  • winform -Label控件
    1、设置标签文本   label1.Text="用一生下载你";2、显示/隐藏控件label1.Visible=true;   //来设置是否隐藏控件 ......
  • wpf翻页
    xaml<ButtonFontSize="16"Margin="10,0"Style="{StaticResourceButtonPrimary}"Content="搜索"Click="SearchClick"Height="35"></Button><StackPanelGrid.Row="2"Horizon......
  • QT常用控件之QTimer,QDialog,QLabel,QLineEdit,QProgressBar,QComboBox,QPushButton,QGridLay
    QT常用控件的组合#ifndefPROGRESSBARWIDGET_H#definePROGRESSBARWIDGET_H#include<QWidget>#include<QTimer>#include<QDialog>#include<QLabel>#include<QLineEdit>#include<QProgressBar>//显示进度条的控件#include<QComboBo......