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 ...
随机推荐
- LUOGU P1290 欧几里德的游戏
题目描述 欧几里德的两个后代Stan和Ollie正在玩一种数字游戏,这个游戏是他们的祖先欧几里德发明的.给定两个正整数M和N,从Stan开始,从其中较大的一个数,减去较小的数的正整数倍,当然,得到的数 ...
- iscroll的滑动效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ajax请求数据以及处理
html <div class="list-block media-list mp0 mbb" data-infos='infos' style="display: ...
- JEECMS二次开发 -------标签使用说明
转载:https://blog.csdn.net/u012176984/article/details/45501771 一:标签套用结构说明 登录后台管理页面,这些嵌套在html中的标签 以[@标签 ...
- oracle-表空间-用户-角色-权限
概要图 概要图 一 表空间 1.1创建表空间 --问题:创建一个名为hp的表空间,指定数据文件为hp.dbf,大小为10m. create tablespace hp datafile 'C:\app ...
- js生成二维码以及插入图片
先根据qrcode官网demo,不同属性值的变化,二维码的变化效果:https://larsjung.de/jquery-qrcode/latest/demo/ 进入demo中,审查元素查看里面引用的 ...
- 几道面试题-考察JS的运用
1.定义一个方法,传入一个string类型的参数,然后将string的每个字符间加个空格返回,比如: spacify('hello world') // => 'h e l l o w o r ...
- 错觉-Info:让你难以置信的视错觉
ylbtech-错觉-Info:让你难以置信的视错觉 1.返回顶部 1. 看下图:如果你看到舞者逆时针旋转说明你用左脑,如果看到顺时针旋转说明你用右脑思维. 据说这是耶鲁大学五年的研究成果. 下图 ...
- Winform实现调用asp.net数据接口实例
本文实例讲述了Winform实现调用asp.net数据接口的方法,分享给大家供大家参考.具体实现方法如下: 一.问题: 最近一个WPF项目需要改写成android项目,思路是在asp.net项目中编写 ...
- arcgis投影测试
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...