WPF custom panel

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows;

namespace WpfApp54
{
    class RadialPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            Size maxSize = Size.Empty;
            foreach (UIElement child in Children)
            {
                child.Measure(availableSize);
                maxSize = new Size(Math.Max(maxSize.Width, child.DesiredSize.Width),
                    Math.Max(maxSize.Height, child.DesiredSize.Height));
            }
            return new Size(double.IsPositiveInfinity(availableSize.Width) ?
                maxSize.Width * 2 : availableSize.Width,
                double.IsPositiveInfinity(availableSize.Height) ?
                maxSize.Height * 2 : availableSize.Height);
        }
         
        public double StartAngle
        {
            get { return (double)GetValue(StartAngleProperty); }
            set { SetValue(StartAngleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StartAngle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StartAngleProperty =
            DependencyProperty.Register("StartAngle", typeof(double), typeof(RadialPanel),
               new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));

        protected override Size ArrangeOverride(Size finalSize)
        {
            var count = Children.Count;
            if (count > 0)
            {
                Point center = new Point(finalSize.Width / 2, finalSize.Height / 2);
                double step = 360 / count;
                int index = 0;
                foreach (UIElement element in Children)
                {
                    double angle = StartAngle + step * index++;
                    angle = (90 - angle) * Math.PI / 180;
                    Rect rc = new Rect(new Point(center.X - element.DesiredSize.Width / 2 +
                        (center.X - element.DesiredSize.Width / 2) * Math.Cos(angle),
                        center.Y - element.DesiredSize.Height / 2 -
                        (center.Y - element.DesiredSize.Height / 2) * Math.Sin(angle)),
                        element.DesiredSize);
                    element.Arrange(rc);
                }
            }
            return finalSize;
        } 
    }
}


//xaml
<Window x:Class="WpfApp54.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:WpfApp54"
        mc:Ignorable="d" WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Slider Margin="4" Maximum="360" x:Name="_startAngle" Grid.Row="1"/>
        <local:RadialPanel StartAngle="{Binding Value,ElementName=_startAngle}">
            <Ellipse Fill="Red" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Green" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Blue" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Red" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Yellow" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Brown" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Orange" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Red" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="LightBlue" Stroke="Black"
                     StrokeThickness="2" Width="40" Height="40"/>
            <Ellipse Fill="Red" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Cyan" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
            <Ellipse Fill="Red" Stroke="Black" StrokeThickness="2"
                     Width="40" Height="40"/>
        </local:RadialPanel>
    </Grid>
</Window>
复制代码

 

 

 

 

 

 

 

 

 

posted @   FredGrit  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示