WPF 线段Line过长渲染出现的问题
来源:互联网 发布:吉林顺通网络的骗局 编辑:程序博客网 时间:2024/05/29 19:58
在使用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>
部分回复:
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 SubPrivate Sub UpdateLineWidth() ScaleBox.StrokeThickness = 1 / _zoomPanTransform.Matrix.M11 XOrigin.StrokeThickness = 1 / _zoomPanTransform.Matrix.M11 YOrigin.StrokeThickness = 1 / _zoomPanTransform.Matrix.M11End 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过长渲染出现的问题
- 数据过长可能出现的问题
- 修正WPF中Line像素不准确的问题
- WPF文字渲染相关的问题及解决
- 因HTTP的Header长度过长导致下载文件名出现乱码的问题
- db2数据库的Clob域出现字符串过长插入失败的问题
- 关于OpenSmtp邮件标题过长后出现乱码问题的解决
- 解决Silverlight插件过长浏览器滚动条不出现的问题
- win10解决安装Markdown2出现html渲染出错的问题
- WPF中,一个由Line控件的StrokeDashArray属性引发的CPU占用率问题
- System.Net.Mail发邮件标题过长出现乱码问题
- WPF下、使用Double作为点坐标带来的问题或line直线颜色不明显的问题的解决方法
- 数据过长,不能插入数据库的问题
- 解决网站URL格式过长的问题
- 处理一列字符过长的问题
- wp7 TextBlock控件内容过长的问题
- Mysql SQL语句过长引起的问题
- 解决Android日志输出过长的问题
- java经典题目_球自由落体
- abstract class和interface有什么区别
- ASIHTTPRequest系列(4):Cookies
- 学习札记
- 一个”flag“标记的小应用
- WPF 线段Line过长渲染出现的问题
- POJ 1080
- 使用JMeter往Mysql中插入数据,数据时成功插入了,但是JDBC请求为什么显示的是报错状态
- Iphone 2D 绘图 - 如何获取图片属性?
- 分层的一点思考
- 闭包实践(二)--函数复合
- ArrayList和Vector的区别
- 一个ie下的兼容性问题
- HashMap和Hashtable的区别