SnapsToDevicePixels问题

3
在我的WPF应用程序中,我创建了几个Line元素,并将它们添加到StackPanel中。所有线的厚度都设置为0.5。但是当我渲染它时,有时会出现一些模糊的线条。我尝试在StackPanel中设置SnapsToDevicePixels,但这使得线条完全不可见。现在,如果我将线条厚度增加到1或大于1,则SnapsToDevicePixels将正常工作。
我创建的Line如下所示:
private void CreateLine(Double y1, Double y2, Double x1, Double x2, Double width, Double height)
{
    Line line = new Line() { Y1 = y1, Y2 = y2, X1 = x1, X2 = x2, Width = width, Height = height };
}

如果将LineThickness设置为0.5,则x1和x2的值将为0.25(LineThickenss / 2),width为0.5(LineThickness)。

在WPF中,是否需要设置最小像素值才能使SnapsToDevicePixels起作用?


你是怎么确定 x1/x2 等于 0.25 的?根据你的代码,它可以是任何值。 - A.R.
对于一条垂直线,我只是将x1和x2的值设置为LineThickness的一半。所以如果LineThickness是0.5,x1和x2将是0.25。此外,线宽度被设置为LineThickness的值。我做错了什么吗?我想创建一条具有定义好的LineThickness的垂直线。 - Lohit
首先,我建议避免设置“宽度”和“高度”。你另一个错误是没有在问题中呈现完整的代码。 - A.R.
3个回答

4

通过使用UseLayoutRounding,我解决了许多SnapToDevicePixels问题:

在你的情况下:

<StackPanel UseLayoutRounding="True">
    ...
</StackPanel>

我不知道这样是否能解决你的问题,但从我的经验来看,值得一试!


UseLayoutRounding在.Net 3.5中不存在。我有一个自定义控件,它针对的是.Net 3.5和4.0两个版本。因此,我必须使用SnapsToDevicePixels。您能告诉我为什么SnapsToDevicePixels在线条粗细(像素值)小于1时无法正常工作吗? - Lohit
也许它会四舍五入到零?尝试使用0.51(为什么不直接使用1.0?) - Ross
没有改变。SnapsToDevicePixels仅在像素值大于或等于1时起作用。 - Lohit

1

不,实际上没有最小值。你所经历的模糊是由于WPF处理绘图的方式造成的。根据我的经验,你无法真正解决这个问题。对设备像素进行捕捉可能会有所帮助,但仍然可能不可预测。

此外,像素和WPF单位之间存在差异,这使得事情更加复杂,尽管许多技术可以在它们之间进行转换。

将像素转换为WPF单位的常见方法是:

Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
double dpiFactor = 1/m.M11;
double lineThickness = dpiFactor * 1;   // Repace '1' with desired pixel size.

这是一篇关于该主题的有用文章: http://www.wpftutorial.net/DrawOnPhysicalDevicePixels.html


我尝试进行上述计算,但仍然没有变化。0.5像素值在 SnapsToDevicePixels 中无法正常工作。有时线条会消失。 - Lohit
我已经编辑了我的问题并提供了创建该行的代码。 - Lohit

1

不建议设置小数位置。

什么是WPF点的一半? WPF将1个点解释为1/96英寸。对于不同的监视器(96 DPI,300 DPI),像素不同。

在通常具有96 DPI的监视器上,WPF将1个点视为1个像素。UIElement.SnapsToDevicePixels非常好用。它尝试将0.5像素捕捉到监视器网格中。有两个结果:放大版本为两个像素或缩短版本为0像素(消失)。

如果出于某种原因需要精确的1像素(而不是1点)定位,则使用GuidelineSet

使用 .NET 4 或更高版本,最好使用布局舍入。它在UI位置测量级别计算像素偏移量。而SnapsToDevicePixels在渲染级别工作。 Layout Rounding的缺点是对于动态移动不利。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接