WPF 线段Line过长渲染出现的问题
在使用WPF的时候,可以做一个实验,在canvas里添加一条线段Line,StrokeThickness属性设置为1,然后通过放大canvas或者调整line起终点,将线段变得很长,你会发现一个奇怪的问题:线段不见了。当你把StrokeThickness设置成2时,它又出现了。
CodeProject和StackOverFlow上也有人提出过类似的问题:
==========================================================================================================================================
http://www.codeproject.com/Questions/192350/Elements-disappearing-on-large-Canvas
I have a large Canvas which can be scrolled horizontally. My Canvas contains little lines (StrokeThickness = 1) positioned uniformly.
When I scroll to right the lines start to disappear and appear when reaching an horizontal offset of 8.000.000 (more or less). How can I fix it?
Here an example. 10 lines to left, 10 lines to right. The first lines are visible while the last ones are partially visible (5 visible, 5 not).
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<ScrollViewer HorizontalScrollBarVisibility="Visible">
<Canvas Width="15000000">
<Line Canvas.Left="0" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="5" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="10" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="15" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="20" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="25" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="30" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="35" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="40" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="45" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999950" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999955" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999960" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999965" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999970" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999975" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999980" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999985" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999990" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
<Line Canvas.Left="14999995" X1="0" X2="0" Y1="0" Y2="100" Stroke="Black" StrokeThickness="1" />
</Canvas>
</ScrollViewer>
</Grid>
</Window>
Thanks,
部分回复:
Solution 1
Instead of using a canvas that's THAT frickin' wide, I'd be owner drawing only what's visible. You're just asking for trouble trying to do it this way.
Since a monitor normally isn't any wider than about 2000 pixels, there's no point in making an image that's 15,000,000 pixels wide.
Solution 2
In this page http://connect.microsoft.com/VisualStudio/feedback/details/731467/disappearing-path-wp[^] you can find the reason of why the lines disappear.
I had the same problem, then i split the lines in function of its length
========================================================================================================================
http://stackoverflow.com/questions/9138891/long-lines-dont-render-correctly
I have a project with a canvas that the user can zoom and pan using the mouse. The origin is marked with a blue cross running through the canvas.
As the user zooms in the line width of the markers is reduced to keep the them about 1 pixel wide on screen. However, after zooming in about 10x
the origin lines abruptly disappear. It seems like the rendering engine is deciding that the line is too small to be displayed before applying the
scaling transform.
What is strange is that when I do the same operation to a rectangle instead of a line I get the expected behavior (see the ScaleBox rectangle
object in the code below). Any ideas on what is causing the problem and how to fix it would be welcome.
Here is the relevant XAML:
<Canvas x:Name="MouseCapture" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="WhiteSmoke" >
<Canvas x:Name="ZoomPan">
<Canvas.RenderTransform >
<MatrixTransform x:Name="_zoomPanTransform" />
</Canvas.RenderTransform>
<Rectangle x:Name="ScaleBox" Width="100" Height="100" Canvas.Left="-50" Canvas.Top="-50" Stroke="Black"/>
<Line x:Name="YOrigin" X1="-5000" X2="5000" Y1="0" Y2="0" Stroke="Blue" />
<Line x:Name="XOrigin" X1="0" X2="0" Y1="-5000" Y2="5000" Stroke="Blue" />
</Canvas>
</Canvas>
And the code behind:
Private Sub ZoomControl_PreviewMouseWheel(sender As Object, e As System.Windows.Input.MouseWheelEventArgs) Handles MouseCapture.PreviewMouseWheel
Dim scale As Double
If e.Delta > 0 Then
scale = 0.95
Else
scale = 1 / 0.95
End If
Dim center As Point = e.GetPosition(MouseCapture)
Dim zoom As New ScaleTransform(scale, scale, center.X, center.Y)
_zoomPanTransform.Matrix *= zoom.Value
UpdateLineWidth()
End Sub
Private Sub UpdateLineWidth()
ScaleBox.StrokeThickness = 1 / _zoomPanTransform.Matrix.M11
XOrigin.StrokeThickness = 1 / _zoomPanTransform.Matrix.M11
YOrigin.StrokeThickness = 1 / _zoomPanTransform.Matrix.M11
End Sub
Here is a screenshot when everything is working.

Here is a screenshot as 10x Zoom. The origin lines have disappeared abruptly, but the black box still shows up as expected.
(Note that only one side of the black box is visible because the rest is outside the visible region because of the zoom.)

部分回复:
The problem was that the line was too long. If I reduce the length of the origin lines dynamically so that they are roughly the same length as the canvas,
everything displays as expected. If the line gets to be 100x or so longer than the canvas they abruptly disappear. This is probably due to some rounding
errors or optimization scheme.
=====================================================================================================================
从以上回复中我们可以找到一点信息:
http://connect.microsoft.com/VisualStudio/feedback/details/731467/disappearing-path-wp
问题:Path with linegeometry disappears
评论:
This is an interesting limit to the processing of WPF vector graphics - in both hardware and software. Empirically, it seems that horizontal or vertical lines
are limited by some ratio related to their stroke thickness.
Here is a table I determined experimentally:
Stroke Thickness Maximum Length (horizontal or vertical)
.07 8750
.8 100,000
.9 112,500
1 125,000
3 375,000
5 625,000
10 1,250,000
100 12,500,000
1000 125,000,004
10000 1,250,000,063
100000 12,500,000,255
This scenario seems to impact a very small number of customers, and there are a couple of workarounds:
1) Introduce a slight diagonal component dramatically increases the limit.
2) Break very long horizontal or vertical lines into pieces.
3) Tweak the thickness a bit.
We apologize for the inconvenience this issue has caused, and we hope you are still successful using WPF in your project.
============================================================================================================================
另外,我在MSDN上找到下面的资料,其中就提到了这一点注意事项:
MSDN: FrameworkElement. Width 属性
这是 FrameworkElement 上的三个用于指定宽度信息的属性之一。 另外两个是 MinWidth 和 MaxWidth。 如果这三个值之间存在冲突,则应用程序确定宽度的实际顺序是:首先必须采用 MinWidth;然后采用 MaxWidth;最后,如果这些值中的每个值都在限制之内,则采用 Width。
此属性的返回值总是与为它设置的任何值相同。与之相反, ActualWidth 的值可能不同。 布局可能已经由于某个原因拒绝了建议的大小。另外,布局系统本身相对于属性系统的 Width 集以异步方式工作,因而可能尚未处理特定大小调整属性的更改。
除了可接受的 Double 值以外,此属性还可以是 Double. NaN 。 此值可用来指定自动调整大小行为。在 XAML 中,可以将该值设置为字符串 "Auto"(不区分大小写)以启用自动调整大小行为。自动调整大小行为意味着元素将填满它可以利用的宽度。但请注意,特定控件通常通过它们的默认样式来提供默认值,以禁用自动调整大小行为,除非特地重新启用了该行为。
除了验证检查以外, Width 还有一个由布局系统实施的非确定性上限值(此值是一个非常大的数字,大于 Single. MaxValue ,但小于 Double. MaxValue )。 如果超出此上限值,元素将不会呈现,并且不会引发异常。不要将 Width 设置为一个远远大于任何可能的视觉显示的最大大小,否则有可能超出此非确定性上限。
=============================================================================================================================
总的来说,问题出现的原因与WPF本身的机制有关,简单地分析就是因为line过长,超出了某个上限值,深层的原因还需要进一步了解。
WPF 线段Line过长渲染出现的问题的更多相关文章
- codeforces #345 (Div. 1) D. Zip-line (线段树+最长上升子序列)
Vasya has decided to build a zip-line on trees of a nearby forest. He wants the line to be as long a ...
- Tunnel Warfare HDU - 1540(线段树最长连续区间)
题意: 一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 解析: 线段树结点 设置一个 lq记录区间左端点开始的最大连续个数, rq ...
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
题意: T个测试数据 n个数 q个查询 n个数 ( 下标从0开始) Q u v 查询 [u, v ] 区间最长连续上升子序列 U u v 把u位置改成v #include<iostream> ...
- Android OpenGL ES(九)绘制线段Line Segment .
创建一个DrawLine Activity,定义四个顶点: float vertexArray[] = { -0.8f, -0.4f * 1.732f, 0.0f, -0.4f, 0.4f * 1.7 ...
- [WPF]DataGridHyperlinkColumn网址过长TextTrimming无效
<DataGridHyperlinkColumn Binding="{Binding source}" Header="来源"> <DataG ...
- WPF 渲染级别 (Tier)
在WPF中,显卡的功能相差很大.当WPF评估显卡时,它会考虑许多因素,包括显卡上的RAM数量.对像素着色器(piexl shader)的支持(计算每个像素效果的内置程序,如透明效果),以及对顶点着色器 ...
- WPF 渲染原理
原文:WPF 渲染原理 在 WPF 最主要的就是渲染,因为 WPF 是一个界面框架.想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的.本文告诉大家 WPF 从开发者告诉如何画图像到在屏幕显示 ...
- WPF 设置纯软件渲染
最近看到有小伙伴说 WPF 使用硬件渲染,如何让 WPF 不使用硬件渲染,因为他觉得性能太好了.万一这个版本发布了,产品经理说下个版本要提升性能就不好了.于是就找到一个快速的方法,让程序不使用硬件渲染 ...
- WPF 基础 - 绘画 1) 线段、矩形、圆弧及填充色
1. 绘画 1.1 图形类型 Line X1.Y1.X2.Y2,Stroke,StrokeThickness Rectangle 矩形 Ellipse 椭圆 Polygon 多边形(自动闭合) Pol ...
随机推荐
- 威胁快报|首爆新型ibus蠕虫,利用热门漏洞疯狂挖矿牟利
一.背景 近日阿里云安全团队发现了一起利用多个流行漏洞传播的蠕虫事件.黑客首先利用ThinkPHP远程命令执行等多个热门漏洞控制大量主机,并将其中一台“肉鸡”作为蠕虫脚本的下载源.其余受控主机下载并运 ...
- NDK(23) 使用CMake 构建 c/c++代码库
1.官网 https://developer.android.com/studio/projects/add-native-code.html 2.android studio 安装相关工具 在打开的 ...
- hdu 5823 color II——子集dp(独立集)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5823 独立集染一种颜色.在这个基础上枚举子集来dp. 状压一样地存边真是美妙. 2^32是1ll<& ...
- 使用pdf.js在移动端预览pdf文档
pdf.js 是一个技术原型主要用于在 HTML5 平台上展示 PDF 文档,无需任何本地技术支持. 在线演示地址:http://mozilla.github.com/pdf.js/web/viewe ...
- 利用jquery模拟select效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- mybatis深入理解(八)-----关联表查询
一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...
- MarioTCP, take it..
MrioTCP,超级马里奥,顾名思义,他不仅高效,而且超级简易和好玩.同时他可以是一个很简洁的Linux C 开发学习工程.毫不夸张的说,如果全部掌握这一个工程,你会成为一个Linux C的牛人:当然 ...
- web服务发展历程
PhP发展历史1.php: 开始名字含义:personal home page 个人网页 现在名字含义:HyperText Perprocessor 超文本预处理语言 预处理: 说明PHP是在服务器预 ...
- Spring_事务
事务管理: 用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当做一个单独的工作单元.这些动作要么全部完成,要么全部不起作用 事务的四个关键属性 原子性 一致性 隔离性 持久性 Spring两 ...
- 深入剖析Redis RDN持久化机制
rdb是redis保存内存数据到磁盘数据的其中一种方式(另一种是AOF).Rdb的主要原理就是在某个时间点把内存中的所有数据的快照保存一份到磁盘上.在条件达到时通过fork一个子进程把内存中的数据写到 ...