您需要将文本中心定位在您计算的点上。因此,您需要将点在 X 方向上移动半个宽度,在 Y 方向上移动半个高度。这会将标签定位在圆的“内部”。像这样:
public class CircleText : FrameworkElement {
public string[] Labels
{
get { return (string[])GetValue(LabelsProperty); }
set { SetValue(LabelsProperty, value); }
}
public static readonly DependencyProperty LabelsProperty =
DependencyProperty.Register("Labels", typeof(string[]), typeof(CircleText), new PropertyMetadata(null, OnLabelsChanged));
private static void OnLabelsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
((CircleText) d).InvalidateVisual();
}
protected override void OnRender(DrawingContext drawingContext) {
if (Labels == null || Labels.Length == 0)
return;
var centerX = this.ActualWidth / 2;
var centerY = this.ActualHeight / 2;
var rad = Math.Min(this.ActualWidth / 2, this.ActualHeight / 2);
for (int i = 0; i < Labels.Length; i++) {
var angle = 360 / (Labels.Length) * i;
var x = centerX + rad * Math.Cos(angle * Math.PI / 180.0);
var y = centerY + rad * Math.Sin(angle * Math.PI / 180.0);
FormattedText text = new FormattedText(
Labels[i],
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Verdana"),
12,
Brushes.Black);
x -= text.Width / 2;
y -= text.Height / 2;
drawingContext.DrawText(text, new Point(x, y));
}
}
}
如果您想在点上画线并且希望标签位于这些线之外 - 您需要根据已计算的 cos 和 sin 值移动标签。这会将标签定位在“外部”,如下所示:
protected override void OnRender(DrawingContext drawingContext) {
if (Labels == null || Labels.Length == 0)
return;
var centerX = this.ActualWidth / 2;
var centerY = this.ActualHeight / 2;
var rad = Math.Min(this.ActualWidth / 2, this.ActualHeight / 2);
for (int i = 0; i < Labels.Length; i++) {
var angle = 360 / (Labels.Length) * i;
var xshift = Math.Cos(angle * Math.PI / 180.0);
var yshift = Math.Sin(angle * Math.PI / 180.0);
var x = centerX + rad * xshift;
var y = centerY + rad * yshift;
drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(centerX, centerY), new Point(x,y));
FormattedText text = new FormattedText(
Labels[i],
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Verdana"),
12,
Brushes.Black);
x -= (1 - xshift) * text.Width / 2;
y -= (1 - yshift) * text.Height / 2;
drawingContext.DrawText(text, new Point(x, y));
}
}
当然,上述方法适用于任意数量的标签。