WPF RingShape

//cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp116
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        } 
    }

    public class RingShape : Shape
    {
        Rect _rect;

        static RingShape()
        {
            StretchProperty.OverrideMetadata(typeof(RingShape),
                new FrameworkPropertyMetadata(Stretch.Uniform,
                FrameworkPropertyMetadataOptions.AffectsMeasure |
                FrameworkPropertyMetadataOptions.AffectsRender));
        }


        public double RingWidth
        {
            get { return (double)GetValue(RingWidthProperty); }
            set { SetValue(RingWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RingWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RingWidthProperty =
            DependencyProperty.Register("RingWidth", typeof(double), typeof(RingShape),
                new FrameworkPropertyMetadata(0.1, FrameworkPropertyMetadataOptions.AffectsRender));

        protected override Geometry DefiningGeometry
        {
            get
            {
                if (_rect.IsEmpty)
                {
                    return Geometry.Empty;
                }
                var rc = _rect;
                rc.Inflate(-RingWidth * _rect.Width, -RingWidth * _rect.Height);
                return new CombinedGeometry(GeometryCombineMode.Exclude,
                    new EllipseGeometry(_rect), new EllipseGeometry(rc));
                
            }
        }

        protected override Size MeasureOverride(Size constraint)
        {
            if (double.IsInfinity(constraint.Width) || double.IsInfinity(constraint.Height))
            {
                _rect = Rect.Empty;
                return Size.Empty;
            }

            double size;
            switch (Stretch)
            {
                case Stretch.Fill:
                    _rect = new Rect(constraint);
                    break;
                case Stretch.Uniform:
                    size = Math.Min(constraint.Width, constraint.Height);
                    _rect = new Rect(new Size(size, size));
                    break;
                case Stretch.UniformToFill:
                    size = Math.Max(constraint.Width, constraint.Height);
                    _rect = new Rect(new Size(size, size));
                    break;
                case Stretch.None:
                    _rect = double.IsNaN(Width) || double.IsNaN(Height) ? Rect.Empty : new Rect(new Size(Width, Height));
                    break;
            }
            
            return _rect.Size;
        }
    }
}


//xaml
<Window x:Class="WpfApp116.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:WpfApp116"
        mc:Ignorable="d"  WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <local:RingShape Fill="Red" Stroke="Black" StrokeThickness="4" RingWidth="0.15"/>
    </Grid>
</Window>

 

posted @ 2024-05-28 20:42  FredGrit  阅读(5)  评论(0编辑  收藏  举报