100165570.htm

来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 162 行 · 第 1/3 页

HTM
162
字号
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;private Pen bluePen = new Pen(Color.Blue, 3);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Pen redPen = new Pen(Color.Red, 2);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected override void OnPaint( PaintEventArgs e )</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnPaint(e);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Graphics dc = e.Graphics;</span></p>
<p class="2" style="MARGIN-TOP: 16.35pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (e.ClipRectangle.Top &lt; 350 || e.ClipRectangle.Left &lt; 250)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rectangle rectangleArea = </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Rectangle (rectangleTopLeft, rectangleSize);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rectangle ellipseArea = </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Rectangle (ellipseTopLeft, ellipseSize);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dc.DrawRectangle(bluePen, rectangleArea);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dc.DrawEllipse(redPen, ellipseArea);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="a6" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">注意这里还把</span><span lang="EN-US">Pen</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">Size</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">Point</span><span style="FONT-FAMILY: 宋体">对象变成成员字段</span><span lang="EN-US" style="LETTER-SPACING: -1pt">&mdash;&mdash; </span><span style="FONT-FAMILY: 宋体">这比每次需要绘图时都创建一个新</span><span lang="EN-US">Pen</span><span style="FONT-FAMILY: 宋体">的效率高。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">运行这个示例,得到如图</span><span lang="EN-US">20-6</span><span style="FONT-FAMILY: 宋体">所示的结果。</span></p>
<p align="center"><span lang="EN-US"><img height="177" src="20/image006.jpg" width="186" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 20-6</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这里有一个问题,图形在</span><span lang="EN-US">300&times;300</span><span style="FONT-FAMILY: 宋体">像素的绘图区域中放不下。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">一般情况下,如果文档太大,不能完全显示,应用程序就会添加滚动条,以便用户滚动窗口,查看其中选中的部分。这是另一个区域,在该区域中如果使用标准控件建立</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">窗体,就让</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">运行环境和基类处理程序。如果窗体上有各种控件,</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 宋体">实例一般知道这些控件在哪里,如果其窗口可能比较小,</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 宋体">实例就知道需要添加滚动条。</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 宋体">实例还会自动添加滚动条,不仅如此,它还可以正确绘制用户滚动到的部分屏幕。此时,用户不需要在代码中做什么工作。但在本章中,我们要在屏幕上绘制图形,所以要帮助</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 宋体">实例确定何时能滚动。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">添加滚动条是很简单的。</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 宋体">仍会处理所有的操作</span><span lang="EN-US" style="LETTER-SPACING: -1pt">&mdash;&mdash; </span><span style="FONT-FAMILY: 宋体">因为它不知道绘图区域有多大。在上面的</span><span lang="EN-US">BigShapes</span><span style="FONT-FAMILY: 宋体">示例中没有滚动条的原因是,</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">不知道它们需要滚动条。我们需要确定的是,矩形的大小从文档的左上角</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">或者是在进行任何滚动前的客户区域左上角</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">开始向下延伸,其大小应足以包含整个文档。本章把这个区域称为文档区域,在图</span><span lang="EN-US">20-7</span><span style="FONT-FAMILY: 宋体">中可以看出,本例的文档区域应是</span><span lang="EN-US">(250, 350)</span><span style="FONT-FAMILY: 宋体">像素。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">很容易确定文档的大小,使用相关的属性</span><span lang="EN-US">Form.AutoScrollMinSize</span><span style="FONT-FAMILY: 宋体">即可。因此给</span><span lang="EN-US">InitializeComponent()</span><span style="FONT-FAMILY: 宋体">方法或</span><span lang="EN-US">Form1</span><span style="FONT-FAMILY: 宋体">构造函数编写下述代码:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void InitializeComponent()</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.AutoScaleBaseSize = new System. Drawing.Size (5,13);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ClientSize = new System.Drawing.Size(292,266);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Name = &quot;Form1&quot;;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Text = &quot;BigShapes&quot;;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.BackColor = Color.White;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.AutoScrollMinSize = new Size(250, 350);</span></p>
<p class="a6" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p align="center"><span lang="EN-US"><img height="242" src="20/image007.gif" width="258" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 20-7</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">另外,</span><span lang="EN-US">AutoScrollMinSize</span><span style="FONT-FAMILY: 宋体">属性还可以用</span><span lang="EN-US">Visual Studio .NET</span><span style="FONT-FAMILY: 宋体">属性窗口设置。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在应用程序启动时设置最小尺寸,并保持不变,在这个应用程序中是必要的,因为我们知道屏幕区域一般有多大。在运行该应用程序时,这个&ldquo;文档&rdquo;是不会改变大小的。但要记住,如果应用程序执行一些如显示文件内容的操作,或者执行某些改变屏幕区域的操作,就需要在其他时间设置这个属性</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">此时,必须手工调整代码,</span><span lang="EN-US">Visual Studio .NET</span><span style="FONT-FAMILY: 宋体">属性窗口只能在构建窗体时设置属性的初始值</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">设置</span><span lang="EN-US">MinScrollSize</span><span style="FONT-FAMILY: 宋体">只是一个开始,但仅有它是不够的。如图</span><span lang="EN-US">20-8</span><span style="FONT-FAMILY: 宋体">所示为示例应用程序目前的外观。</span></p>
<p align="center"><span lang="EN-US"><img height="176" src="20/image008.jpg" width="186" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 20-8</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">注意,不仅窗体正确地设置了滚动条,而且它们的大小也正确设置了,以指定文档正确显示的比例。可以试着在运行示例时重新设置窗口的大小,这样就会发现滚动条会正确响应,甚至如果使窗口变得足够大,不再需要滚动条时,滚动条就会消失。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">但是,如果使用一个滚动条,并向下滚动它,会发生什么情况呢?如图</span><span lang="EN-US">20-9</span><span style="FONT-FAMILY: 宋体">所示。显然,出现了错误!</span></p>
<p align="center"><span lang="EN-US"><img height="178" src="20/image009.jpg" width="188" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 20-9</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">实际上,出错的原因是我们没有在</span><span lang="EN-US">OnPaint()</span><span style="FONT-FAMILY: 宋体">重写方法代码中考虑滚动条的位置。如果最小化窗口,再恢复它,重新绘制一遍窗口,就可以很清楚地看出这一点。结果如图</span><span lang="EN-US">20-10</span><span style="FONT-FAMILY: 宋体">所示。</span></p>
<p align="center"><span lang="EN-US"><img height="177" src="20/image010.jpg" width="186" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 20-10</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">图形像以前一样进行了绘制,矩形的左上角嵌套在客户区域的左上角,就好像根本没有移动过滚动条一样。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在更正这个问题前,先介绍一下在这些屏幕图上发生了什么情况。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">首先从</span><span lang="EN-US">BigShapes</span><span style="FONT-FAMILY: 宋体">示例开始,如图</span><span lang="EN-US">20-8</span><span style="FONT-FAMILY: 宋体">所示。在这个例子中,整个窗口刚被恢复,重新绘制整个窗口。看看前面的代码,该代码的作用是使</span><span lang="EN-US">graphics</span><span style="FONT-FAMILY: 宋体">实例用左上角坐标</span><span lang="EN-US">(0,0)(</span><span style="FONT-FAMILY: 宋体">相对于窗口客户区域的左上角</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">绘制一个矩形<span style="LETTER-SPACING: -1pt">&mdash;&mdash;</span></span><span style="LETTER-SPACING: -1pt"> </span><span style="FONT-FAMILY: 宋体">它是已经绘制过的。问题是,</span><span lang="EN-US">graphics</span><span style="FONT-FAMILY: 宋体">实例在默认情况下把坐标解释为是相对于客户窗口的,它不知道滚动条的情况。代码还没有尝试为滚动条的位置调整坐标。椭圆也是这样。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">下面处理图</span><span lang="EN-US">20-9</span><span style="FONT-FAMILY: 宋体">的问题。在滚动后,注意窗口上半部分显示正确,这是因为它们是在应用程序第一次启动时绘制的。在滚动窗口时,</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">没有要求应用程序重新绘制已经显示在屏幕中的内容。</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">只指出屏幕上目前显示的内容可以平滑地移动,以匹配滚动条的位置。这是一个非常高效的过程,因为它也能使用某些硬件加速来完成。在这个屏幕图中,有错误的是窗口下部的</span><span lang="EN-US">1/3</span><span style="FONT-FAMILY: 宋体">部分。在应用程序第一次显示时,没有绘制这部分窗口,因为在滚动窗口前,这部分在客户区域的外部。这表示</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">要求</span><span lang="EN-US">BigShapes</span><span style="FONT-FAMILY: 宋体">应用程序绘制这个区域。它引发</span><span lang="EN-US">Paint</span><span style="FONT-FAMILY: 宋体">事件,把这个区域作为剪切的矩形。这也是</span><span lang="EN-US">OnPaint()</span><span style="FONT-FAMILY: 宋体">重载方法完成的任务。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">问题的另一种表达方式是我们把坐标表示为相对于文档开头的左上角</span><span lang="EN-US" style="LETTER-SPACING: -1pt">&mdash;&mdash; </span><span style="FONT-FAMILY: 宋体">需要转换它们,使之相对于客户区域的左上角。图</span><span lang="EN-US">20-11</span><span style="FONT-FAMILY: 宋体">说明了这一点。</span></p>
<p align="center"><span style="MARGIN-TOP: 12px; Z-INDEX: 9; LEFT: 0px; MARGIN-LEFT: 189px; WIDTH: 189px; POSITION: absolute; HEIGHT: 132px"><img height="132" src="20/image011.gif" width="189" alt="" /></span><span lang="EN-US"><img height="200" src="20/image012.jpg" width="210" alt="" /></span></p>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?