如何有人告诉你,请你画出1像素的线,是不是觉得很简单,实际上在 WPF 上还是比较难的。 本文告诉大家,如何让画出的线不模糊
画出线的第一个方法,创建一个 Canvas ,添加一个线
界面代码
<Canvas x:Name="Canvas"></Canvas>
在后台添加一条线
Line myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.Black;
myLine.X1 = 100;
myLine.X2 = 200; // 150 too far
myLine.Y1 = 200;
myLine.Y2 = 200;
myLine.StrokeThickness = 1;
Canvas.Children.Add(myLine);
那么如何看到线模糊呢?
简单方法是使用 ViewBox 和放大镜,可以看到模糊
在界面添加下面代码
<Viewbox >
<Canvas x:Name="Canvas"></Canvas>
</Viewbox>
这时拖动窗口可以看到线放大
可以看到线是模糊的,如果想要让线不模糊,可以添加下面的代码
myLine.SnapsToDevicePixels = true;
myLine.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
这个方法是从 [https://stackoverflow.com/q/2879033/6116637][https://stackoverflow.com/q/2879033/6116637]得到,但是无法对于自己的控件
如果自己创建一个控件,那么直接使用 dc.DrawLine 得到不是清晰的
创建一个类自定义控件,添加下面的代码画出线
protected override void OnRender(DrawingContext dc)
{
dc.DrawLine(_pen, new Point(10, 10), new Point(310, 10));
}
可以看到,画出来的线是模糊的,于是看了微软的代码
看了他的矩形是如何画的,看到他画出来的是清晰的,但是复制他的代码到我的控件,画出来不是清晰的
/// <summary>
/// Render callback.
/// </summary>
protected override void OnRender(DrawingContext drawingContext)
{
Pen pen = GetPen();
drawingContext.DrawRoundedRectangle(Fill, pen, _rect, RadiusX, RadiusY);
}
下面代码是我复制他的,但是自己的控件画出来在放大时,线模糊,所以直接复制是无法做到wr的矩形那样
protected override void OnRender(DrawingContext dc)
{
dc.DrawRoundedRectangle(null, _pen, new Rect(new Point(10, 10), new Size(100, 100)), 5, 5);
}
在界面画出来wr 的矩形和自定义控件,可以看到,微软的是清晰的
那么是不是wr 做了特殊的东西,到现在还不知道,但是找到了一个方法,可以画出清晰
缩小看到的图片是这样
那么放大时就是下面这张图
所以需要在放大时,也画一个像素, 这个方法就是本文,所以这是在翻译,只是没有使用对所有的文字翻译,来自工藤大神的方法。
本文使用的方法很简单,第一步
复制方法到一个静态类
public static void DrawSnappedLinesBetweenPoints(this DrawingContext dc,
Pen pen, double lineThickness, params Point[] points)
{
var guidelineSet = new GuidelineSet();
foreach (var point in points)
{
guidelineSet.GuidelinesX.Add(point.X);
guidelineSet.GuidelinesY.Add(point.Y);
}
var half = lineThickness / 2;
points = points.Select(p => new Point(p.X + half, p.Y + half)).ToArray();
dc.PushGuidelineSet(guidelineSet);
for (var i = 0; i < points.Length - 1; i = i + 2)
{
dc.DrawLine(pen, points[i], points[i + 1]);
}
dc.Pop();
}
然后就可以在自定义控件使用下面的代码
protected override void OnRender(DrawingContext dc)
{
dc.DrawSnappedLinesBetweenPoints(_pen,1, new[]
{
new Point(10, 10),
new Point(310, 10),
});
}
可以看到线是清晰的
参见:https://stackoverflow.com/a/45189552/6116637
http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx
本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/WPF-%E5%A6%82%E4%BD%95%E7%94%BB%E5%87%BA1%E5%83%8F%E7%B4%A0%E7%9A%84%E7%BA%BF.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 lindexi (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。