Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用GDI+;合法地滚动;?_C#_.net_User Controls_Gdi+_Scroll - Fatal编程技术网

C# 如何使用GDI+;合法地滚动;?

C# 如何使用GDI+;合法地滚动;?,c#,.net,user-controls,gdi+,scroll,C#,.net,User Controls,Gdi+,Scroll,在GDI+中,用户控件中是否有首选的快速滚动方法 我创建了一个控件,以图形方式呈现水平可滚动的数据图 目前,我的控件通过将水平滚动条的位置转换为数据的偏移来操作。然后,该控件渲染存在于该起点和基于控件宽度计算的终点之间的数据 这种方法有效,但速度很慢。我不希望在每次滚动事件时必须手动重新绘制整个控件表面。相反,我希望通过将整个(或部分)图形数据绘制到屏幕外表面来初始化控件,然后通过使控件从水平滚动条位置计算的偏移量开始读取预渲染的图形数据来虚拟滚动控件表面 BitBlt是唯一的方法吗?我真的必须

在GDI+中,用户控件中是否有首选的快速滚动方法

我创建了一个控件,以图形方式呈现水平可滚动的数据图

目前,我的控件通过将水平滚动条的位置转换为数据的偏移来操作。然后,该控件渲染存在于该起点和基于控件宽度计算的终点之间的数据

这种方法有效,但速度很慢。我不希望在每次滚动事件时必须手动重新绘制整个控件表面。相反,我希望通过将整个(或部分)图形数据绘制到屏幕外表面来初始化控件,然后通过使控件从水平滚动条位置计算的偏移量开始读取预渲染的图形数据来虚拟滚动控件表面

BitBlt是唯一的方法吗?我真的必须手动将图形数据从一个曲面复制到另一个曲面吗?难道我不能接管绘制事件并使其在渲染时从屏幕外表面读取数据吗?这样,复制和渲染操作是一个整体

或者,我应该直接在面板控件上画画,然后从左向右滚动面板本身吗

澄清
本质上,我想知道滚动预渲染数据的正确方法。如何在控件中滚动图形数据?重新绘制预渲染的图形不是正确的选项。

是的,我会尝试双缓冲。如果渲染为屏幕外位图,只需滚动位图即可

您可以尝试将整个图形渲染为一个大位图,并让滚动条移动它。但是,如果图形非常大,则需要将位图的大小限制在可见区域,只绘制它可见的内容,并像现在一样处理虚拟滚动

在32位WindowsXP上测试时,我发现限制大约在2.379亿像素左右。这对于大多数控件来说当然足够了,但对于您的应用程序来说可能还不够

出于好奇,以下是我们能够创建和使用的最大Windows位图大小:

Width Height Area (pixels) ====== ====== =========== 32,767 7,261 237,921,187 25,000 9,517 237,925,000 23,792 10,000 237,920,000 20,000 11,896 237,920,000 15,861 15,000 237,915,000 15,000 15,861 237,915,000 11,896 20,000 237,920,000 10,000 23,792 237,920,000 9,517 25,000 237,925,000 7,261 32,767 237,921,187 宽度高度区域(像素) ====== ====== =========== 32,767 7,261 237,921,187 25,000 9,517 237,925,000 23,792 10,000 237,920,000 20,000 11,896 237,920,000 15,861 15,000 237,915,000 15,000 15,861 237,915,000 11,896 20,000 237,920,000 10,000 23,792 237,920,000 9,517 25,000 237,925,000 7,261 32,767 237,921,187
整个可滚动绘图的表面能有多大?你总是画所有的点还是只画那些你知道是可见的点?我只画那些在可见区域内的点。绘图的整个区域最多可以是控件宽度的200倍。我想创建一个大约是控制面大小两倍的图形缓冲区,并在必要时通过只读取设置块大小所需的数据来重新填充缓冲区。如何通过将屏幕外位图的区域复制到屏幕上位图来“仅滚动位图”?在C#中,通过传入引用并将偏移量滚动到某个GDI+函数中,可以使用几个Graphics.DrawImage覆盖将图像的一部分绘制到指定位置。您可以构建一个位图,然后从滚动位置和控件可见区域的大小开始绘制矩形。@James,是的,这就是Paul的意思。您的问题“我不能接管绘制事件并使其在渲染时从屏幕外表面读取数据吗?”表明了您的误解。绘制事件本身不做任何事情——它不渲染;它只是通知您的代码它需要绘制一些东西。因此,使用DrawImage()绘制预渲染图像的一部分是一种正确的滚动方式。