我正在使用DrawingContext
类来绘制条形图,但生成的标签和刻度是模糊的:
在代码中,我使用了一个BarRenderer
派生自FrameworkElement
. 每个条都由一个BarRenderer
实例表示,我通过覆盖该OnRender
方法进行绘图。每个“条”都有一个label
和一个下面的文本并value
定义条的高度。而负责绘制label和tick的逻辑如下:label
value
private void DrawLabel(DrawingContext drawingContext, FormattedText text, double x, double y, int direction)
{
drawingContext.DrawLine(_blackPen, new Point(Width * 0.5, y), new Point(Width * 0.5, y + 6));
y += 6;
if (LabelRotationDegree != 0)
{
RotateTransform rotateTransform = new RotateTransform(-LabelRotationDegree, 0.5 * Width, y + text.Height * 0.5);
TranslateTransform translateTransform = new TranslateTransform(0, direction * text.WidthIncludingTrailingWhitespace * 0.5);
drawingContext.PushTransform(translateTransform);
drawingContext.PushTransform(rotateTransform);
}
drawingContext.DrawText(text, new Point(x, y));
if (LabelRotationDegree != 0)
{
drawingContext.Pop();
drawingContext.Pop();
}
}
我怀疑问题出在旋转变换上,因为当标签没有被变换时,它们不再像以前那样模糊:
但可以看出,一些蜱比其他蜱更暗。那么我做错了什么?
编辑:
我已经设置SnapsToDevicePixels
为true
,当我设置为时RenderOptions.SetEdgeMode
,Aliased
一些刻度消失并且文字仍然模糊:
编辑 2:更多代码
public class GraphUnitRenderer : FrameworkElement
{
private const double TEXT_SIZE = 12;
private const double KEY_LABELS_HEIGHT = 50;
private readonly Typeface _typeface;
private readonly CultureInfo _cultureInfo;
private readonly Pen _blackPen;
private readonly Pen _bluePen;
private readonly Pen _tickBlackPen;
private readonly Pen _whitePen;
public BarData Data { get; set; }
//Some properties
public GraphUnitRenderer()
{
_typeface = new Typeface("Segoe UI");
_cultureInfo = CultureInfo.CurrentCulture;
_blackPen = new Pen(Brushes.Black, 1);
_bluePen = new Pen(Brushes.Blue, 1);
_tickBlackPen = new Pen(Brushes.Black, 2);
_whitePen = new Pen(Brushes.White, 1);
/*
_blackPen.Freeze();
_bluePen.Freeze();
_tickBlackPen.Freeze();
_whitePen.Freeze();
*/
RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
SnapsToDevicePixels = true;
}
protected override void OnRender(DrawingContext drawingContext)
{
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
FormattedText keyText = GetText(Data.Key);
//Bar drawing logic
if (LabelDisplayIsForced || (LabelRotationDegree == 0 && keyText.WidthIncludingTrailingWhitespace < Width) || (LabelRotationDegree != 0 && keyText.Height < Width))
DrawLabel(drawingContext, keyText, 0.5 * (Width - keyText.WidthIncludingTrailingWhitespace), GetYPosition(1) + 1, 1);
}
private void DrawLabel(DrawingContext drawingContext, FormattedText text, double x, double y, int direction)
{
drawingContext.DrawLine(_blackPen, new Point(Width * 0.5, y), new Point(Width * 0.5, y + 6));
y += 6;
if (LabelRotationDegree != 0)
{
RotateTransform rotateTransform = new RotateTransform(-LabelRotationDegree, 0.5 * Width, y + text.Height * 0.5);
TranslateTransform translateTransform = new TranslateTransform(0, direction * text.WidthIncludingTrailingWhitespace * 0.5);
drawingContext.PushTransform(translateTransform);
drawingContext.PushTransform(rotateTransform);
}
drawingContext.DrawText(text, new Point(x, y));
if (LabelRotationDegree != 0)
{
drawingContext.Pop();
drawingContext.Pop();
}
}
private double GetYPosition(double position) => Height - position - KEY_LABELS_HEIGHT;
private FormattedText GetText(string text) => new FormattedText(text, _cultureInfo, FlowDirection.LeftToRight, _typeface, TEXT_SIZE, Brushes.Black, VisualTreeHelper.GetDpi(this).PixelsPerDip);
}