Files
HandyControl/HandyControl/Controls/Panel/CirclePanel.cs
T
2018-12-27 17:05:05 +08:00

70 lines
2.8 KiB
C#

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Controls
{
public class CirclePanel : Panel
{
public static readonly DependencyProperty DiameterProperty = DependencyProperty.Register(
"Diameter", typeof(double), typeof(CirclePanel), new FrameworkPropertyMetadata(170.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double Diameter
{
get => (double) GetValue(DiameterProperty);
set => SetValue(DiameterProperty, value);
}
public static readonly DependencyProperty KeepVerticalProperty = DependencyProperty.Register(
"KeepVertical", typeof(bool), typeof(CirclePanel), new FrameworkPropertyMetadata(ValueBoxes.FalseBox, FrameworkPropertyMetadataOptions.AffectsMeasure));
public bool KeepVertical
{
get => (bool) GetValue(KeepVerticalProperty);
set => SetValue(KeepVerticalProperty, value);
}
public static readonly DependencyProperty OffsetAngleProperty = DependencyProperty.Register(
"OffsetAngle", typeof(double), typeof(CirclePanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsMeasure));
public double OffsetAngle
{
get => (double) GetValue(OffsetAngleProperty);
set => SetValue(OffsetAngleProperty, value);
}
// ReSharper disable once RedundantAssignment
protected override Size MeasureOverride(Size availableSize)
{
if (Children.Count == 0) return new Size(Diameter, Diameter);
availableSize = new Size(Diameter, Diameter);
var i = 0;
var perDeg = 360.0 / Children.Count;
var radius = Diameter / 2;
foreach (UIElement element in Children)
{
element.Measure(availableSize);
var centerX = element.DesiredSize.Width / 2.0;
var centerY = element.DesiredSize.Height / 2.0;
var angle = perDeg * i++ + OffsetAngle;
var transform = new RotateTransform
{
CenterX = centerX,
CenterY = centerY,
Angle = KeepVertical ? 0 : angle
};
element.RenderTransform = transform;
var r = Math.PI * angle / 180.0;
var x = radius * Math.Cos(r);
var y = radius * Math.Sin(r);
var rectX = x + availableSize.Width / 2 - centerX;
var rectY = y + availableSize.Height / 2 - centerY;
element.Arrange(new Rect(rectX, rectY, element.DesiredSize.Width, element.DesiredSize.Height));
}
return availableSize;
}
}
}