我有一个直接绘制到自定义画布的控件。自定义控件根据物理尺寸计算绘制圆的大小。无论我使用Ellipse XAML元素还是自定义绘制控件,我所看到的行为都是相同的。
基本上,一旦元素的大小变得足够大于画布的最小尺寸,它的绘制位置就会从剪切矩形偏移。最终结果是中心点(由不同的控件绘制)是正确的,但圆圈被移动 - 并且边缘被剪裁。
示例:
只要我计算的中心和实际中心对齐,控件就会正确显示。我无法找到任何明确设置剪辑的地方。
我的问题是2折:
如何准确地渲染到排列区域的中心?我正在使用以下方法计算中心点:
Point center = new Point( RenderSize.Width / 2, RenderSize.Height / 2);
大部分时间都可以使用,但是当圆圈超出一定大小时就不会有效。
圆形控制代码:
public class CirclePoint : UIElement
{
// field
double radius;
// additional properties
MetersPerPixel -- set by container, attached property, affects measure
RadiusInMeters -- set by application, affects measure
FillColor -- set by application, affects render
ObjectColor -- set by applicaiton, affects render
StrokeThickness -- set by application, affects measure, render
Location -- center point, set by application, affects layout
protected override Size MeasureOverride(Size constraint)
{
base.MeasureOverride(constraint);
radius = RadiusInMeters / MetersPerPixel;
double halfPenWidth = StrokThickness / 2;
double diameter = 2 * (radius + halfPenWidth);
return new Size(diameter, diameter);
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
SolidColorBrush fillBrush = // from FillColor, frozen
SolidColorBrush edgeBrush = // from ObjectColor, frozen
Pen edgePen = // from edgeBrush, StrokeThickness, frozen
double halfPenWidth = StrokeThickness / 2;
drawingContext.DrawEllipse(fillBrush, edgePen,
new Point(RenderSize.Width / 2, RenderSize.Height / 2),
radius - halfPenWidth, radius - halfPenWidth);
}
}
对于缩写表示法很抱歉,但我正在尝试用相关信息汇总锅炉铭牌代码。
自定义面板要复杂得多,因为它负责消除标签等冲突,但相关信息如下:
public class PhysicalPane : Pane
{
// Pertinent Properties
PhysicalArea // affects layout
protected override Size MeasureOverride(Size constraint)
{
Size screen = new Screen(ActualWidth, ActualHeight);
double metersPerDisplayUnit = // calculation based on screen and other context
Size newDesiredSize = // from constraint, adjusting for double.Infinity
foreach(UIElement child in InternalChildren)
{
child.Measure(constraint);
SetMetersPerPixel(child, metersPerDisplayUnit);
newDesiredSize.Width = Math.Max(newDesiredSize.Width, child.DesiredSize.Width);
newDesiredSize.Height = Math.Max(newDesiredSize.Height, child.DesiredSize.Height);
}
return newDesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach(UIElement child in InternalChildren)
{
Location childLocation = GetLocation(child);
// LocationToPoint is very well tested.
Point displayPoint = LocationToPoint(childLocation, PhysicalArea, finalSize);
displayPoint.X -= child.DesiredSize.Width / 2;
displayPoint.Y -= child.DesiredSize.Height / 2;
Rect locationRect = new Rect(displayPoint, child.DesiredSize);
child.Arrange(locationRect);
}
return finalSize;
}
}
事实证明,圆圈的位置是错误的,因为DesiredSize和RenderSize是不同的。要修复我CirclePoint
中的展示位置,我必须更改中心点逻辑,如下所示:
double xOffset = (DesiredSize.Width - RenderSize.Width) / 2;
double yOffset = (DesiredSize.Width - RenderSize.Width) / 2;
Point center = new Point(xOffset + radius, yOffset + radius);
此解决方案仍存在一个问题:
答案 0 :(得分:0)
这应该返回UIElement的中心:
@Override
public boolean select(final Viewer viewer, final Object parentElement, final Object element) {
final String filterString = filterText.getText().toLowerCase();
if (filterString.length() == 0) { return true; }
final mydata myData= (mydata) element;
if (filterString.matches("columnName" + ".+")) {
index = filterString.indexOf("columnName" + ".+");
evaluateText(myData, filterString, i, index + tableColumnsText[i].length())
}
public boolean evaluateText(final mydata data, final String filterText, final int beginningIndex) {
subString = filterText.substring(beginningIndex, filterText.length());
return evaluateString(data.getString(), subString);
}
public boolean evaluateString(final String cellString, final String commaString) {
int countSubstrings = 0;
final String[] items = commaString.split(",");
countSubstrings = items.length;
for (final String s : items) {
if (s.length() != 0) {
if (!cellString.contains(s)) { return false; }
}
}
return true;
}
答案 1 :(得分:0)
事实证明,我的定位问题的答案是,一旦孩子在任何维度上比父容器更大,DesiredSize和RenderSize之间存在差异。我必须像这样调整我的OnRender
方法:
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
SolidColorBrush fillBrush = // from FillColor, frozen
SolidColorBrush edgeBrush = // from ObjectColor, frozen
Pen edgePen = // from edgeBrush, StrokeThickness, frozen
double halfPenWidth = StrokeThickness / 2;
double xOffset = (DesiredSize.Width - RenderSize.Width) / 2;
double yOffset = (DesiredSize.Width - RenderSize.Width) / 2;
Point center = new Point(xOffset + radius, yOffset + radius);
drawingContext.DrawEllipse(fillBrush, edgePen, center,
radius - halfPenWidth, radius - halfPenWidth);
}
无论相对于父母的圆圈有多大,这都允许在正确的位置绘制圆圈。
我的裁剪问题是由于布局窗格有ClipToBounds=True
。这完全是另一个问题。