Reputation: 999
I'm implementing some drag/drop functionality on a treeview.
I'm trying to draw an insertion point marker, but it's coming out blurry:
How can I make it render crisply and sharp?
This is my template:
<HierarchicalDataTemplate DataType="{x:Type localvm:TreeViewItemViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}">
<i:Interaction.Behaviors>
<b:TreeViewItemDragBehavior/>
<b:TreeViewItemDropBehavior/>
</i:Interaction.Behaviors>
</TextBlock>
This is my render logic:
protected override void OnRender(DrawingContext drawingContext)
{
Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
SolidColorBrush renderBrush = new SolidColorBrush(Colors.Blue);
renderBrush.Opacity = 0.5;
Pen renderPen = new Pen(new SolidColorBrush(Colors.Blue), 1.5);
if (IsInUpperHalf)
{
drawingContext.DrawLine(renderPen, adornedElementRect.TopLeft, adornedElementRect.TopRight);
Point point1 = new Point(adornedElementRect.TopLeft.X + 10, adornedElementRect.TopLeft.Y);
Point point2 = new Point(adornedElementRect.TopLeft.X, adornedElementRect.TopLeft.Y + 3);
StreamGeometry leftStreamGeometry = new StreamGeometry();
using (StreamGeometryContext geometryContext = leftStreamGeometry.Open())
{
geometryContext.BeginFigure(adornedElementRect.TopLeft, true, true);
PointCollection points = new PointCollection { point1, point2 };
geometryContext.PolyLineTo(points, true, true);
drawingContext.DrawGeometry(Brushes.Blue, new Pen(Brushes.Blue, 1), leftStreamGeometry);
}
StreamGeometry rightStreamGeometry = new StreamGeometry();
using (StreamGeometryContext geometryContext = rightStreamGeometry.Open())
{
geometryContext.BeginFigure(adornedElementRect.TopRight, true, true);
PointCollection points = new PointCollection { point3, point4 };
geometryContext.PolyLineTo(points, true, true);
drawingContext.DrawGeometry(Brushes.Blue, new Pen(Brushes.Blue, 1), rightStreamGeometry);
}
}
}
I've been playing with UseLayoutRounding
and SnapToDevicePixels
in the adorner constructor but it seems I'm missing something.
Upvotes: 1
Views: 395
Reputation: 999
With the guidance of Brian and some tinkering this seems to fix the issue. The main problem I kept having after Brian's comment was that the guidlines needed half a pen width extra for them to work. I only found this out by searching for examples, but no hint on MSDN. Here is my functioning code:
protected override void OnRender(DrawingContext drawingContext)
{
Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
Pen renderPen = new Pen(new SolidColorBrush(Colors.Blue), 1);
double halfPenWidth = renderPen.Thickness / 2;
GuidelineSet guidelines = new GuidelineSet();
guidelines.GuidelinesX.Add(adornedElementRect.TopLeft.X + halfPenWidth);
guidelines.GuidelinesX.Add(adornedElementRect.BottomRight.X + halfPenWidth);
guidelines.GuidelinesY.Add(adornedElementRect.TopLeft.Y + halfPenWidth);
guidelines.GuidelinesY.Add(adornedElementRect.BottomRight.Y + halfPenWidth);
drawingContext.PushGuidelineSet(guidelines);
if (IsInUpperHalf)
{
drawingContext.DrawLine(renderPen, adornedElementRect.TopLeft, adornedElementRect.TopRight);
StreamGeometry leftStreamGeometry = new StreamGeometry();
using (StreamGeometryContext geometryContext = leftStreamGeometry.Open())
{
geometryContext.BeginFigure(adornedElementRect.TopLeft, true, true);
geometryContext.LineTo(new Point(adornedElementRect.TopLeft.X + 10, adornedElementRect.TopLeft.Y), false, false);
geometryContext.LineTo(new Point(adornedElementRect.TopLeft.X, adornedElementRect.TopLeft.Y + 3), false, false);
drawingContext.DrawGeometry(Brushes.Blue, new Pen(Brushes.Blue, 1), leftStreamGeometry);
}
StreamGeometry rigthStreamGeometry = new StreamGeometry();
using (StreamGeometryContext geometryContext = rigthStreamGeometry.Open())
{
geometryContext.BeginFigure(adornedElementRect.TopRight, true, true);
geometryContext.LineTo(new Point(adornedElementRect.TopRight.X, adornedElementRect.TopRight.Y + 3), false, false);
geometryContext.LineTo(new Point(adornedElementRect.TopRight.X - 10, adornedElementRect.TopRight.Y), false, false);
drawingContext.DrawGeometry(Brushes.Blue, new Pen(Brushes.Blue, 1), rigthStreamGeometry);
}
}
}
Upvotes: 1