出于某种原因,饼图菜单不会在“框”内呈现。很抱歉,我不知道“盒子”的用语是什么(见图片)。因此我很难解决这个问题,因为我不知道这个术语是什么,我得到的结果完全不相关
因此,当我想移动/缩放饼图菜单时,它变得扭曲(就像在图片中,它的宽度 疯了)正如您所看到的,#2应该是元素的正常方式,但在#1中,整个饼图菜单超出了“框”
如何限制饼图切片在“框”内呈现?这个控件我从这里得到它,我用它做的就是添加自定义属性。
代码(不是我的,它属于作者,我只是添加了一些属性)
protected override Size MeasureOverride(Size availablesize)
{
foreach (UIElement element in Children)
{
element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
}
return availablesize;
}
protected override Size ArrangeOverride(Size finalsize)
{
double radx = this.DesiredSize.Width / 2.0;
double rady = this.DesiredSize.Height / 2.0;
Point center = new Point(radx, rady);
double angle = 0.0, anglestep = 0.0;
if (this.Children.Count != 0.0)
anglestep = TotalAngle / (double)this.Children.Count;
double deg2rad = Math.PI / 180.0;
foreach (UIElement uie in Children)
{
double a = (angle + anglestep / 2.0) * deg2rad;
uie.Arrange(new Rect(Point.Add(center, new Vector((radx + (double)base.GetValue(CircularPieMenu.ClippingRadiusProperty)) * Math.Cos(a) / 2.0 - uie.DesiredSize.Width / 2.0,
(rady + (double)base.GetValue(CircularPieMenu.ClippingRadiusProperty)) * Math.Sin(a) / 2.0 - uie.DesiredSize.Height / 2.0)),
uie.DesiredSize));
angle += anglestep;
}
return finalsize;
}
protected override void OnRender(DrawingContext dc)
{
double radx = this.DesiredSize.Width / 2.0;
double rady = this.DesiredSize.Height / 2.0;
Size radiusSize = new Size(radx, rady);
Point center = new Point(radx, rady);
double currentAngle = 0.0;
double angleStep = 0.0;
if (this.Children.Count != 0.0)
{
angleStep = TotalAngle / (double)this.Children.Count;
}
double deg2rad = Math.PI / 180.0;
// this is the code where caused the "hole" in the center of the "ellipse"
EllipseGeometry entirePart = new EllipseGeometry(center, radx + 1, rady + 1);
EllipseGeometry excludedPart = new EllipseGeometry(center, ClippingRadius, ClippingRadius);
dc.PushClip(new CombinedGeometry(GeometryCombineMode.Exclude, entirePart, excludedPart));
// this produce a full ellipse (not like arc segment like u would think)
// we want to have arcs, instead of a full ellipse :D
dc.DrawEllipse(BackgroundColor, new Pen(OuterCircumferenceColor, OuterCircumferenceThickness), center, radx, rady);
if (ClippingRadius > 0.0)
{
dc.DrawEllipse(null, new Pen(InnerCircumferenceColor, 1.0), center, ClippingRadius + 1, ClippingRadius + 1);
}
double startAngle = 0.0, endAngle = 0.0;
foreach (UIElement element in this.Children)
{
double angle = currentAngle * deg2rad;
// line between segments
dc.DrawLine(new Pen(LineColor, LineThickness), center, Point.Add(center, new Vector(radx * Math.Cos(angle), rady * Math.Sin(angle))));
if (this.IsMouseOver && element.IsMouseOver)
{
startAngle = angle;
endAngle = startAngle + angleStep * deg2rad;
}
currentAngle += angleStep;
}
// only related when mouse down
if (this.IsMouseOver)
{
PathGeometry path = new PathGeometry();
PathFigure pathfig = new PathFigure();
pathfig.StartPoint = center;
pathfig.Segments.Add(new LineSegment(Point.Add(center, new Vector(radx * Math.Cos(startAngle), rady * Math.Sin(startAngle))), true));
pathfig.Segments.Add(new ArcSegment(Point.Add(center, new Vector(radx * Math.Cos(endAngle), rady * Math.Sin(endAngle))), new Size(1.0, 1.0), 0.0, false, SweepDirection.Clockwise, true));
pathfig.Segments.Add(new LineSegment(center, true));
path.Figures.Add(pathfig);
dc.PushClip(path);
currentAngle = 0;
if (this.ismouseleftdown)
{
dc.DrawEllipse(ForegroundColor, new Pen(new SolidColorBrush(Color.FromRgb(171, 161, 140)), 1.0), center, radx, rady);
dc.DrawEllipse(null, new Pen(new LinearGradientBrush(Color.FromRgb(223, 183, 136), Colors.Transparent, 45.0), 1.0), center, radx - 1, rady - 1);
if ((double)base.GetValue(CircularPieMenu.ClippingRadiusProperty) > 0.0)
dc.DrawEllipse(null, new Pen(new SolidColorBrush(Color.FromRgb(171, 161, 140)), 1.0), center, (double)base.GetValue(CircularPieMenu.ClippingRadiusProperty) + 1, (double)base.GetValue(CircularPieMenu.ClippingRadiusProperty) + 1);
foreach (UIElement uie in this.Children)
{
double a = currentAngle * deg2rad;
dc.DrawLine(new Pen(new SolidColorBrush(Color.FromRgb(171, 161, 140)), 1.0), center, Point.Add(center, new Vector(radx * Math.Cos(a), rady * Math.Sin(a))));
currentAngle += angleStep;
}
}
else
{
// chg to mouse over color circumference color
dc.DrawEllipse(ForegroundColor, new Pen(new SolidColorBrush(Color.FromRgb(210, 192, 141)), 1.0), center, radx, rady);
//dc.DrawEllipse(null, new Pen(new LinearGradientBrush(Color.FromRgb(255, 255, 247), Colors.Transparent, 45.0), 1.0), center, radx - 1, rady - 1);
if ((double)base.GetValue(CircularPieMenu.ClippingRadiusProperty) > 0.0)
dc.DrawEllipse(null, new Pen(new SolidColorBrush(Color.FromRgb(210, 192, 141)), 1.0), center, (double)base.GetValue(CircularPieMenu.ClippingRadiusProperty) + 1, (double)base.GetValue(CircularPieMenu.ClippingRadiusProperty) + 1);
foreach (UIElement uie in this.Children)
{
double a = currentAngle * deg2rad;
dc.DrawLine(new Pen(new SolidColorBrush(Color.FromRgb(210, 192, 141)), 1.0), center, Point.Add(center, new Vector(radx * Math.Cos(a), rady * Math.Sin(a))));
currentAngle += angleStep;
}
}
dc.Pop();
}
dc.Pop();
}
答案 0 :(得分:1)
“测量覆盖”只是返回它获得的可用大小。它不应该是那样的。它应该返回控件及其子项所需的大小。有关WPF中的两遍布局系统,请参阅此link。
在你的情况下,控件应该找到PIE的直径,并且应该作为尺寸约束返回。
答案 1 :(得分:0)
使用Math.Min(RenderSize.Width / 2,RenderSize.Height / 2)。
总结问题的原因:粗心的错误。