基于C#的波形顯示控件的實(shí)現(xiàn)[附完整源碼下載]_第1頁
基于C#的波形顯示控件的實(shí)現(xiàn)[附完整源碼下載]_第2頁
基于C#的波形顯示控件的實(shí)現(xiàn)[附完整源碼下載]_第3頁
基于C#的波形顯示控件的實(shí)現(xiàn)[附完整源碼下載]_第4頁
基于C#的波形顯示控件的實(shí)現(xiàn)[附完整源碼下載]_第5頁
已閱讀5頁,還剩62頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、編者記:09年暑假正好在學(xué)院實(shí)驗(yàn)室呆了一段時間,做了個完整的上位機(jī)軟件(具體實(shí)現(xiàn):根據(jù)下位機(jī)的指令,實(shí)現(xiàn)通過串口來操縱下位機(jī)進(jìn)行實(shí)驗(yàn),并將采集的數(shù)據(jù)進(jìn)行處理和保存,并以圖形的方式顯示),整個項(xiàng)目邊學(xué)C# WinForm邊設(shè)計,這個波形顯示控件就是項(xiàng)目中的一部分,也花了自己絕大多數(shù)時間。暑假一結(jié)束,也就沒有再去接觸C#了,主要精力放在C+,Windows編程上去了。此外,順便將該波形顯示控件當(dāng)作自己畢業(yè)設(shè)計的內(nèi)容,下文實(shí)際上是節(jié)選自自己的本科畢業(yè)論文的呵呵,希望對大家能有所幫助。由于自己是個C#新手,所以代碼以及文章有疏漏、錯誤、不妥之處在所難免,歡迎交流哈(現(xiàn)在看著十個月前寫的代碼,感想頗多.

2、)歡迎轉(zhuǎn)載,但請注明出處(通宵整理排版 = =  很不容易的哈)(寫這篇文章之時,大學(xué)再一個半月就結(jié)束了,目前在學(xué)C+、Windows編程、希望能找到個適合的工作吧) “基于C#的波形顯示控件”設(shè)計于09年暑假 源代碼奉上呵呵:博客園下載 | CSDN下載 解壓密碼:CSharp_WinForm_Waveform基于C#的波形顯示控件的實(shí)現(xiàn)寫于2009年9月   跳到文章目錄(注意這里是采用錨鏈接,訂閱的朋友可能訪問會失效的,例如QQ郵箱中的訂閱= = 還是訪問原文吧)“基于C#的波形顯示控件的演示程序”為配套控件使用而設(shè)計的(演示程序源代碼同控件源代碼

3、一起奉上了) 下面先上幾張圖,大家可以先了解最后做出來是個什么東西:   再奉上兩個波形顯示控件的演示視頻(兩個視頻內(nèi)容差不多的呵呵):        摘    要計算機(jī)技術(shù)的飛速發(fā)展使得其在自動化系統(tǒng)中的應(yīng)用日益增強(qiáng)。大量監(jiān)控、圖像數(shù)據(jù)顯示軟件活躍在自動化工業(yè)及自動化教學(xué)領(lǐng)域。同時,軟件系統(tǒng)的日益復(fù)雜化使得模塊化開發(fā)變得尤為重要。本課題所設(shè)計的基于C#的波形顯示控件就可在微軟.NET平臺下進(jìn)行代碼功能重用,達(dá)到模塊化開發(fā)和快速開發(fā)的目的,使得程序員能夠集

4、中精力設(shè)計軟件的具體業(yè)務(wù)流程,而不必?fù)?dān)心波形呈現(xiàn)的問題。本文先介紹了.NET平臺下用戶控件開發(fā)的基本方法,以及用C#描述的GDI+圖形開發(fā)技術(shù),然后提出一種基于C#的波形顯示控件的設(shè)計思路,并對波形坐標(biāo)值轉(zhuǎn)換、坐標(biāo)標(biāo)尺、工具欄、局部放大等具體的設(shè)計細(xì)節(jié)進(jìn)行詳細(xì)解析。本課題設(shè)計的波形顯示控件實(shí)現(xiàn)了同時顯示多條數(shù)據(jù)曲線、局部放大查看、波形顯示自動調(diào)整最佳坐標(biāo)范圍、動態(tài)顯示波形等功能。創(chuàng)新之處在于設(shè)計了一種方法,使得波形顯示控件的坐標(biāo)軸的起點(diǎn)值和終點(diǎn)值能夠以浮點(diǎn)數(shù)顯示,并自動根據(jù)當(dāng)前波形顯示控件的大小,描繪出符合用戶視覺的坐標(biāo)標(biāo)尺。最后,還設(shè)計了一個波形顯示控件的演示程序,用于介紹該控件的使用方法以

5、及功能測試,并提出了該波形顯示控件可改進(jìn)的地方。 關(guān)鍵詞:波形顯示控件;C#;GDI+;動態(tài)波形目  錄(注意這里是采用錨鏈接,訂閱的朋友可能訪問會失效的,例如QQ郵箱中的訂閱= = 還是訪問原文吧)1 緒論1.1 課題背景1.2 波形顯示控件實(shí)現(xiàn)的功能2 主要開發(fā)技術(shù)介紹2.1 .NET用戶控件介紹2.2 GDI+技術(shù)介紹3 波形顯示控件整體設(shè)計3.1 數(shù)據(jù)存儲結(jié)構(gòu)的設(shè)計3.2 控件界面模塊的設(shè)計3.3 控件工作流程的設(shè)計4 波形顯示控件各細(xì)節(jié)的實(shí)現(xiàn)4.1 坐標(biāo)值和標(biāo)尺的實(shí)現(xiàn)4.1.1 坐標(biāo)相關(guān)的成員變量4.1.2 坐標(biāo)標(biāo)定權(quán)值的概念4.1.3 坐標(biāo)標(biāo)尺的繪制4.1.4

6、子標(biāo)尺線的選擇性顯示4.2 數(shù)據(jù)點(diǎn)的描繪4.2.1 數(shù)據(jù)值轉(zhuǎn)換為坐標(biāo)值4.2.2 溢出坐標(biāo)范圍的數(shù)據(jù)點(diǎn)的處理4.2.3 遍歷所有數(shù)據(jù)線并繪制出4.3 波形顯示區(qū)域網(wǎng)格的實(shí)現(xiàn)4.3.1 網(wǎng)格相關(guān)的成員變量4.3.2 網(wǎng)格的繪制4.4 工具欄按鈕的實(shí)現(xiàn)4.4.1 工具欄按鈕相互關(guān)系4.4.2 工具欄提示標(biāo)簽的實(shí)現(xiàn)4.5 波形放大功能的實(shí)現(xiàn)4.5.1 局部放大選擇框的實(shí)現(xiàn)4.5.2 放大選擇框的鼠標(biāo)操作4.5.3 放大選擇框的按鈕操作4.5.4 更新數(shù)據(jù)顯示范圍為放大的范圍4.6 坐標(biāo)自動調(diào)整及恢復(fù)默認(rèn)坐標(biāo)的實(shí)現(xiàn)4.6.1 坐標(biāo)自動調(diào)整功能4.6.2 恢復(fù)默認(rèn)坐標(biāo)范圍功能4.7 波形顯示控件接口的實(shí)

7、現(xiàn)4.7.1 控件基本屬性4.7.2 控件外觀樣式4.7.3 控件繪圖接口4.8 波形顯示控件其他細(xì)節(jié)的處理4.8.1 坐標(biāo)值產(chǎn)生遮蓋時的處理4.8.2 波形顯示控件大小改變時的處理4.8.3 按鈕點(diǎn)擊時進(jìn)行禁用操作4.8.4 右鍵菜單的顯示4.8.5 XML注釋以及智能提示5 波形顯示控件功能的演示和使用5.1 波形顯示控件演示程序的設(shè)計5.2 波形顯示控件功能的演示5.2.1 外觀樣式的更改5.2.2 波形顯示演示5.2.3 波形顯示控件在實(shí)際項(xiàng)目中的使用6 課題總結(jié)參考文獻(xiàn) 1  緒論1.1  課題背景波形顯示控件廣泛見于監(jiān)控測量,圖像數(shù)據(jù)顯示等自動化相關(guān)軟

8、件中,更是組態(tài)軟件必不可少的一部分。例如美國國家儀器有限公司(National Instruments)的NI Measurement Studio集成式套件以及LabView圖形化程序開發(fā)環(huán)境等,都包含技術(shù)成熟的波形顯示控件,功能豐富且強(qiáng)大。目前購買成熟的自動控制相關(guān)的第三方控件庫往往需要支付較高的費(fèi)用,且大多數(shù)項(xiàng)目只用到些許專業(yè)性控件,例如一個噴管實(shí)驗(yàn)平臺軟件,圖形用戶界面只需要波形顯示控件、U型差計控件和壓力表控件,因此不適合科研機(jī)構(gòu)以及中小型軟件開發(fā)公司。所以掌握簡單的控件開發(fā)技術(shù),并開發(fā)屬于自己團(tuán)隊或公司的控件庫,從而降低軟件開發(fā)成本,顯得十分必要。微軟的.NET解決方案依據(jù)其對已有

9、代碼的互操作性、簡化部署、分布式、高效開發(fā)等諸多優(yōu)點(diǎn),完全勝任自動化系統(tǒng)軟件的開發(fā)。C#是微軟為.NET平臺開發(fā)的一門語言,通過.NET平臺可以輕松使用GDI+技術(shù)開發(fā)可重用的用戶圖形界面控件。GDI+是目前在Windows窗體應(yīng)用程序中以編程方式呈現(xiàn)圖形的唯一方法,它使程序設(shè)計者可以創(chuàng)建圖形、繪制文本以及將圖形圖像作為對象操作,旨在提供較好的性能并且易于使用。波形顯示控件因?yàn)樯婕暗阶鴺?biāo)系、數(shù)據(jù)顯示方式、精確度、實(shí)時性等因素,存在一定的開發(fā)難度。本課題意在使用微軟.NET平臺下的C#語言,提供一種坐標(biāo)計算方法,解決自動調(diào)整最佳坐標(biāo)范圍,以符合用戶視覺的方式顯示坐標(biāo)標(biāo)尺,并通過GDI+技術(shù)顯示波

10、形數(shù)據(jù),具有一定的實(shí)際開發(fā)參考價值。開發(fā)完成后的波形顯示控件,可以快速嵌入到.NET平臺下的軟件工程中,開發(fā)者只需簡單的操作,就可以使用該控件友好地顯示波形數(shù)據(jù),從而達(dá)到快速開發(fā)的目的?;氐侥夸?.2  波形顯示控件實(shí)現(xiàn)的功能本課題所設(shè)計的波形顯示控件,主要實(shí)現(xiàn)以下功能:(1)    多條波形數(shù)據(jù)的顯示。該波形顯示控件能夠同時顯示多條波形數(shù)據(jù),用戶能夠控制每條波形數(shù)據(jù)的顯示顏色、線寬、線帽、以及線轉(zhuǎn)折的樣式。并且提供了三種波形數(shù)據(jù)顯示的方式:連續(xù)數(shù)據(jù)線、離散點(diǎn)、條形圖。(2)    友好坐標(biāo)標(biāo)尺的顯示。該波形顯示控件能夠根據(jù)

11、當(dāng)前顯示數(shù)據(jù)的坐標(biāo)范圍,友好地顯示坐標(biāo)標(biāo)尺。例如X軸坐標(biāo)起始值為34.2,結(jié)束坐標(biāo)值為100.7,則控件不是簡單得將坐標(biāo)10等分并顯示并不友好的坐標(biāo)值,而是通過計算當(dāng)前波形顯示控件的大小,顯示40、50這樣的友好的坐標(biāo)值,并判斷是否需要繼續(xù)在40到50的坐標(biāo)值之間顯示更小分度的坐標(biāo)值。(3)    波形顯示區(qū)域網(wǎng)格的顯示。該波形顯示控件可以顯示同坐標(biāo)標(biāo)尺的坐標(biāo)線相對應(yīng)的網(wǎng)格,使得用戶能夠更直觀地觀察波形數(shù)據(jù)。(4)    波形的局部放大。該波形顯示控件提供了波形局部放大的功能。并根據(jù)實(shí)際使用和測試,控制了波形放大的精度,以免產(chǎn)生數(shù)據(jù)溢

12、出的問題。(5)    坐標(biāo)自動調(diào)整。該波形顯示控件能夠根據(jù)當(dāng)前要顯示的波形數(shù)據(jù)的值,自動選擇最佳的坐標(biāo)范圍,來直觀地在控件的波形顯示區(qū)域顯示完整的波形曲線。(6)    外觀顏色方案的修改。該波形顯示控件能夠修改外觀樣式,諸如背景色、網(wǎng)格顏色、坐標(biāo)線顏色、坐標(biāo)值顏色等都可以進(jìn)行調(diào)整,以使控件外觀能夠符合軟件整體風(fēng)格。(7)    其他細(xì)節(jié)。該波形顯示控件還設(shè)計了一個工具欄,可以方面地使用網(wǎng)格顯示、局部放大、坐標(biāo)自動調(diào)整、恢復(fù)默認(rèn)坐標(biāo)功能。另外還設(shè)計右鍵菜單,能夠顯示當(dāng)前鼠標(biāo)位置的具體坐標(biāo)值,以及工具欄按

13、鈕的快捷按鈕?;氐侥夸?  主要開發(fā)技術(shù)介紹2.1  .NET用戶控件介紹在微軟.NET平臺下,可以設(shè)計出在應(yīng)用程序內(nèi)部或應(yīng)用程序之間提供一致性行為和用戶界面的復(fù)合控件,即用戶控件。用戶控件可以是某個應(yīng)用程序的本地控件,也可以編譯成DLL供多個應(yīng)用程序使用。用戶控件極大限度的幫助程序員進(jìn)行代碼重用和快速開發(fā)。通常用戶控件通過繼承UserControl基類,并組合微軟提供的基礎(chǔ)控件,如Button控件、PictureBox控件、Label控件等,然后進(jìn)行功能的擴(kuò)充和組合,從而創(chuàng)建出特定功能的用戶控件。在Visual Studio 2005下使用C#開發(fā).NET用戶控件,可以通

14、過新建Windows控件庫來實(shí)現(xiàn)。創(chuàng)建成功后軟件會自動從UserControl基類繼承一個類,并允許通過設(shè)計視圖添加所需要的已有控件。圖 21  設(shè)計用戶控件界面 設(shè)計好大致的界面后,就可以著手設(shè)計具體的代碼,用戶控件通常通過對消息處理函數(shù)的編寫,來實(shí)現(xiàn)特定的功能,并將控件中的各個模塊聯(lián)系起來。用戶控件還需要設(shè)計出公開的接口屬性和方法給控件的使用者,這樣控件的使用者就能夠調(diào)用公開的屬性和方法,來實(shí)現(xiàn)對控件的操作和控制。另外,在編寫控件的時候?qū)Ω鱾€屬性和方法編寫XML注釋,并在生成控件的時候輸出XML文檔文件,這樣控件使用者在使用該控件的時候,能夠享受Visual Studi

15、o智能提示帶來的便利。 編譯運(yùn)行后可以檢查基本的控件效果:圖 22  用戶控件的調(diào)試運(yùn)行 最后可以通過項(xiàng)目屬性設(shè)置程序集信息。圖 23  設(shè)置程序集信息 這樣,一個用戶控件就設(shè)計完成了。用戶控件自身不能獨(dú)立作為程序運(yùn)行,需要嵌入到特定的軟件中。可以通過選擇工具箱,添加新創(chuàng)建的.NET Framework組件,添加到工具箱中。其用法同微軟提供的基礎(chǔ)控件一樣,可以通過拖拽的方式進(jìn)行使用?;氐侥夸?.2  GDI+技術(shù)介紹GDI+是.NET Framework類庫,用于進(jìn)行圖形編程。它是一種基于GDI的技術(shù),GDI即Windows Grap

16、hical Device Interface,是Windows API(應(yīng)用程序編程接口)中處理圖形的部分。GDI+是目前在Windows窗口應(yīng)用程序中以編程方式呈現(xiàn)圖形的唯一方法,它使程序設(shè)計者可以創(chuàng)建圖形、繪制文本以及將圖形圖像作為對象操作,旨在提供較好的性能并且易于使用。GDI+技術(shù)在Windows應(yīng)用程序中得到了廣泛的應(yīng)用,使得Windows圖形圖像編程變得格外得容易。目前Windows平臺下的大量應(yīng)用軟件的圖形界面通過GDI+技術(shù)實(shí)現(xiàn)。利用GDI+技術(shù)可以方便地在屏幕、打印機(jī)或者其他輸出設(shè)備上輸出圖形、文本等內(nèi)容,程序員無需關(guān)心硬件設(shè)備和設(shè)備驅(qū)動,就可以編寫出設(shè)備無關(guān)的應(yīng)用程序。一些

17、新興的信息化軟件通過GDI+技術(shù)能實(shí)現(xiàn)動態(tài)交互的高級效果,比如可視化電子地圖。在使用GDI+繪圖之前,需要獲得繪圖對象Graphics,通常在編寫控件的Paint事件時,Graphics對象可通過PaintEventArgs參數(shù)獲得。所有的繪制過程都是面向?qū)ο蟮?,例如?shí)例化1像素的實(shí)線黑色畫筆并繪制線條,可用如下的方式創(chuàng)建:Graphics Grap = e.Graphics;Pen p = new Pen(Color.Black);Grap.DrawLine(p, 0, 0, 100, 100);p.Dispose();若填充一個區(qū)域的顏色,則代碼樣式如下所示:SolidBrush b =

18、new SolidBrush(Color.Red);Grap.FillRectangle(b,0,0,10,10);b.Dispose();其直觀的操作方式使得程序員能快速繪制橢圓,橢圓弧,矩形,貝塞爾曲線,路徑等。通過GDI+技術(shù)創(chuàng)建自定義控件能實(shí)現(xiàn)各種功能。只需要在建立自定義控件后,編寫響應(yīng)Paint事件的代碼,通過GDI+技術(shù)繪制必須的圖形,就可以控制自定義控件的外觀。本課題設(shè)計的波形顯示控件,大量得運(yùn)用了GDI+技術(shù)進(jìn)行繪圖操作,使得控件能夠呈現(xiàn)出出色的界面效果?;氐侥夸?  波形顯示控件整體設(shè)計3.1  數(shù)據(jù)存儲結(jié)構(gòu)的設(shè)計本課題設(shè)計的波形顯示控件主要用于顯示數(shù)據(jù)點(diǎn)

19、集合。數(shù)據(jù)點(diǎn)集合具有大小不確定性,因此可以使用.NET提供的泛型支持,其主要的優(yōu)點(diǎn)是性能,因此要顯示的數(shù)據(jù)集合可以使用泛型集合中的List<T>類存儲,List<T>類可以動態(tài)增大和減少其容量。同時考慮到波形顯示控件需能夠同時顯示多條曲線,且數(shù)據(jù)點(diǎn)集合根據(jù)X軸的值和Y軸的值分別創(chuàng)建List<float>。經(jīng)過上面分析,得出波形顯示控件內(nèi)部需要創(chuàng)建兩個List<List<float>>對象,一個用于存儲要顯示的數(shù)據(jù)點(diǎn)集合的X軸值的引用,另一個用于存儲要顯示的數(shù)據(jù)點(diǎn)集合的Y軸值的引用。另外,還需要創(chuàng)建List<color>、L

20、ist<int>、List<LineJoin>、List<LineCap>、List<DrawStyle>分別來存儲每條要顯示的數(shù)據(jù)點(diǎn)集合的顏色、線條寬度、連接點(diǎn)樣式、起始線帽、樣式。其中DrawStyle為自定義枚舉,用于標(biāo)識畫圖樣式:線條、點(diǎn)或者條形圖。具體代碼設(shè)計如下所示:public enum DrawStyle Line,dot,bar private List<List<float>> _listX = new List<List<float>>(); /X軸數(shù)據(jù)集2·priv

21、ate List<List<float>> _listY = new List<List<float>>(); /Y軸數(shù)據(jù)集private List<Color> _listColor = new List<Color>(); /線條顏色private List<int> _listWidth = new List<int>(); /線條寬度private List<LineJoin> _listLineJoin = new List<LineJoin>(); /連接點(diǎn)pri

22、vate List<LineCap> _listLineCap = new List<LineCap>(); /起始線帽private List<DrawStyle> _listDrawStyle = new List<DrawStyle>(); /樣式由上面可知,波形顯示控件實(shí)際上本身是不存儲實(shí)際的數(shù)據(jù)值的,而相當(dāng)于存儲了要顯示的數(shù)據(jù)的“引用”,即實(shí)現(xiàn)的是一個無源控件,這樣有利于數(shù)據(jù)處理層和數(shù)據(jù)呈現(xiàn)層的分離,使軟件更趨向于模塊化。另一方面,為實(shí)現(xiàn)多波形顯示帶來了效率:只需引用傳遞波形顯示控件要顯示的數(shù)據(jù),而無需整體地復(fù)制所有的顯示數(shù)據(jù)給波形顯示

23、控件?;氐侥夸?.2  控件界面模塊的設(shè)計控件的界面可以通過使用微軟提供的基礎(chǔ)控件進(jìn)行布局。首先使用5個pictureBox控件分別表示底部的X軸坐標(biāo)區(qū)域、左側(cè)的Y軸坐標(biāo)區(qū)域、頂部標(biāo)題欄區(qū)域、右側(cè)工具欄區(qū)域、以及中間的波形顯示區(qū)域。除中間波形顯示區(qū)域的pictureBox控件外,其余4個pictureBox控件大小有所限制,這樣有助于坐標(biāo)顯示的計算。具體參數(shù)如下表所示:表格 31   控件界面5大模塊區(qū)域控件類型控件名稱控件大小底部X軸坐標(biāo)區(qū)域PictureBoxpictureBoxBottom高度固定45像素左側(cè)Y軸坐標(biāo)區(qū)域PictureBoxpictureBoxLeft

24、寬度固定50像素頂部標(biāo)題欄區(qū)域PictureBoxpictureBoxTop高度固定30像素右側(cè)工具欄區(qū)域PictureBoxpictureBoxRight寬度固定50像素中間波形顯示區(qū)域PictureBoxpictureBoxGraph不設(shè)置固定值 右側(cè)工具欄區(qū)域中,需要更多控件來標(biāo)識工具欄,參數(shù)如下表所示: 表格 32  工具欄模塊作用控件類型控件名稱控件大小底部背景PanelpanelControlItem36,178內(nèi)部滑動背景PanelpanelItemsIN34,178網(wǎng)格顯示按鈕ButtonbuttonLinesShowXY32,32放大選取框功能按

25、鈕ButtonbuttonBigModeXY32,32坐標(biāo)自動調(diào)整按鈕ButtonbuttonAutoModeXY32,32默認(rèn)坐標(biāo)范圍按鈕ButtonbuttonReXY32,32工具欄上移按鈕ButtonbuttonControlItemUP36,10工具欄下移按鈕ButtonbuttonItemsDown36,10工具欄提示標(biāo)簽LabellabelItemShuoMing100,32 其中的內(nèi)部滑動背景Panel、工具欄上移按鈕和工具欄下移按鈕是為今后功能擴(kuò)充的時候預(yù)留的。當(dāng)工具欄的工具按鈕過多的時候,可以通過上移按鈕和下移按鈕進(jìn)行工具欄中項(xiàng)目的滾動。本課題實(shí)際設(shè)計過程中,上移

26、按鈕和下移按鈕是處于禁用狀態(tài)。另外,工具欄提示標(biāo)簽初始為隱藏狀態(tài),只有在鼠標(biāo)經(jīng)過工具欄按鈕的時候,工具欄提示標(biāo)簽則移動到指定位置處并顯示相應(yīng)的提示文字。在實(shí)際使用過程中,還存在一個波形局部放大的功能,可以通過一個半透明的PictureBox控件實(shí)現(xiàn),另外還需要兩個按鈕:放大和取消。參數(shù)如下表所示:表格 33  波形局部放大模塊作用控件類型控件名稱控件大小半透明的放大框PictureBoxpictureBoxBigXY根據(jù)實(shí)際操作兩個按鈕的容器PanelpanelBigXY83,32放大按鈕ButtonbuttonBigXYBig40,32取消按鈕ButtonbuttonBigXYQu

27、it40,32 具體設(shè)計結(jié)果如下圖所示: 圖 31  控件界面模塊的設(shè)計  波形顯示區(qū)域還提供了右鍵菜單的功能,具體參數(shù)如下表: 表格 34右鍵菜單模塊作用控件類型控件名稱標(biāo)識菜單ContextMenuStripMenuRightClick當(dāng)前位置X坐標(biāo)值ToolStripTextBoxToolStripTextBoxX當(dāng)前位置Y坐標(biāo)值ToolStripTextBoxToolStripTextBoxY網(wǎng)格顯示ToolStripMenuItem網(wǎng)格顯示ToolStripMenuItem放大選取框功能ToolStripMenuItem放大

28、選取框功能ToolStripMenuItem坐標(biāo)自動調(diào)整ToolStripMenuItem坐標(biāo)自動調(diào)整ToolStripMenuItem默認(rèn)坐標(biāo)范圍ToolStripMenuItem默認(rèn)坐標(biāo)范圍ToolStripMenuItem回到目錄3.3  控件工作流程的設(shè)計波形顯示控件設(shè)置了兩個影響顯示方式的標(biāo)記:標(biāo)識當(dāng)前是否處于放大查看模式,以及標(biāo)識當(dāng)前坐標(biāo)是否自動調(diào)整以適合窗口大小。作為波形顯示控件的私有成員變量,如下所示:private bool _isBigModeXY = false; /是否處于放大查看模式private bool _isAutoModeXY = true; /是否

29、自動調(diào)整以適合窗口大小若當(dāng)前處于放大模式,則波形在動態(tài)顯示的時候,并不自動改變X軸和Y軸的坐標(biāo)范圍(即使有數(shù)據(jù)點(diǎn)越出波形顯示控件的顯示范圍),只有在放大選取框進(jìn)行局部放大的時候改變X軸和Y軸的坐標(biāo)范圍。若當(dāng)前非放大模式,且為自動調(diào)整坐標(biāo)模式,則遍歷要顯示的數(shù)據(jù)值,確定要顯示的最大坐標(biāo)范圍,然后修改X軸和Y軸的坐標(biāo)范圍。整個波形顯示控件的顯示方式判斷和實(shí)現(xiàn)過程,設(shè)計為在中間波形顯示區(qū)域pictureBoxGraph的OnPaint消息中。具體波形顯示的工作流程如下所示:圖 32  控件工作流程  4  波形顯示控件各細(xì)節(jié)的實(shí)現(xiàn)4.1  坐標(biāo)值和標(biāo)

30、尺的實(shí)現(xiàn)4.1.1  坐標(biāo)相關(guān)的成員變量因?yàn)榭丶嬖诰植糠糯蟮墓δ?,所以局部放大后的坐?biāo)軸起始值和結(jié)束值通常會是浮點(diǎn)數(shù)。僅僅根據(jù)坐標(biāo)軸兩點(diǎn)的浮點(diǎn)數(shù)值難以描繪出符合用戶視覺的坐標(biāo)線和坐標(biāo)值。因此引入了坐標(biāo)標(biāo)定值的概念,得到下列私有成員變量:private float _fXBegin; /當(dāng)前顯示波形的X軸起始坐標(biāo)值private float _fXEnd; /當(dāng)前顯示波形的X軸結(jié)束坐標(biāo)值private float _fYBegin; /當(dāng)前顯示波形的Y軸起始坐標(biāo)值private float _fYEnd; /當(dāng)前顯示波形的Y軸結(jié)束坐標(biāo)值private float _fXBeginGO

31、; /當(dāng)前顯示波形的X軸坐標(biāo)標(biāo)定起始值private float _fXEndGO; /當(dāng)前顯示波形的X軸坐標(biāo)標(biāo)定結(jié)束值private float _fYBeginGO; /當(dāng)前顯示波形的Y軸坐標(biāo)標(biāo)定起始值private float _fYEndGO; /當(dāng)前顯示波形的Y軸坐標(biāo)標(biāo)定結(jié)束值具體的意義如下圖所示:圖 41  坐標(biāo)相關(guān)成員變量的意義 由上圖可知,_fXBegin和_fXEnd代表的即為實(shí)際的坐標(biāo)起始值和結(jié)束值(如上圖中的起點(diǎn)值0和終點(diǎn)值60),而_fXBeginGo和_fXEndGo在用戶使用波形顯示控件的時候并不會顯示出來,僅僅用于內(nèi)部坐標(biāo)標(biāo)尺的計算,見下圖:圖

32、 42  _fXBeginGo和_fXEndGo的意義 其具體表示的值通常在波形顯示控件表示范圍的外側(cè),上圖中_fXBegin的值為21.67,而_fXBeginGo的值為10,_fXEnd的值為52.96,而_fXEndGo的值為60。這樣設(shè)計坐標(biāo)就能夠根據(jù)_fXBeginGo和_fXEndGo設(shè)計出符合用戶視覺的坐標(biāo)線和坐標(biāo)值,例如上圖中顯示的坐標(biāo)值30、40、50,并不是簡單地將_fXBegin和_fXEnd等分得到的。回到目錄4.1.2  坐標(biāo)標(biāo)定權(quán)值的概念在確定了雙坐標(biāo)模式后(坐標(biāo)值和坐標(biāo)標(biāo)定值)。用坐標(biāo)值來描述實(shí)際的坐標(biāo)軸的端點(diǎn)坐標(biāo),用坐標(biāo)標(biāo)定值來描述

33、整個坐標(biāo)標(biāo)尺的坐標(biāo)線和坐標(biāo)軸上的子坐標(biāo)。這樣就需要保證坐標(biāo)標(biāo)定值要為簡單的數(shù)據(jù),例如-10、30、0.05等,即保證該浮點(diǎn)值中只有一位是非零的。于是引入了坐標(biāo)標(biāo)定權(quán)值的概念,定義如下:private float _fXQuanBeginGO; /當(dāng)前顯示波形的X軸坐標(biāo)標(biāo)定起始權(quán)值private float _fXQuanEndGO; /當(dāng)前顯示波形的X軸坐標(biāo)標(biāo)定結(jié)束權(quán)值private float _fYQuanBeginGO; /當(dāng)前顯示波形的Y軸坐標(biāo)標(biāo)定起始權(quán)值private float _fYQuanEndGO; /當(dāng)前顯示波形的Y軸坐標(biāo)標(biāo)定結(jié)束權(quán)值坐標(biāo)標(biāo)定權(quán)值表示的是一個浮點(diǎn)數(shù)最高非零位

34、對應(yīng)的權(quán),例如34的坐標(biāo)標(biāo)定權(quán)值為10,0.036的坐標(biāo)標(biāo)定權(quán)值為0.01,0的坐標(biāo)標(biāo)定權(quán)值設(shè)定為1。坐標(biāo)軸刻度線和刻度值通過坐標(biāo)標(biāo)定值來實(shí)現(xiàn)。因此,可以設(shè)計一個函數(shù),來計算一個浮點(diǎn)數(shù)的坐標(biāo)標(biāo)定權(quán)值:private float _getQuan(float m);以X軸舉例,_fXBegin為21.67則計算得到的_fXQuanBeginGO為10,_fXQuanEndGO為52.96則計算得到的權(quán)值為10。之后就可以通過權(quán)值來修改_fXBeginGo和_fXEndGo,即最后得到的_fXBeginGo為10,_fXEndGo為60。因此,在21.67到52.96范圍內(nèi)描繪出的子坐標(biāo)值為30、

35、40、50。同樣的,如果有需要的話,可以方便得將30到40之間的坐標(biāo)標(biāo)尺繼續(xù)分割下去?;氐侥夸?.1.3  坐標(biāo)標(biāo)尺的繪制在繪制坐標(biāo)標(biāo)尺前,先判斷起始坐標(biāo)權(quán)值和結(jié)束坐標(biāo)權(quán)值哪個大,并從權(quán)值大的方向往權(quán)值小的方向繪制標(biāo)尺。計算出當(dāng)前權(quán)值下可分多少段坐標(biāo),而后轉(zhuǎn)換為實(shí)際要描繪的像素位置(在pictureBoxBottom和pictureBoxLeft中)。if (_fXQuanBeginGO <= _fXQuanEndGO) /X軸從右往左畫 / linesQuan = _fXQuanEndGO; /獲得兩權(quán)的大值 linesNum = (_fXEndGO - _fXBeginGO

36、) / linesQuan; /可以分成的線段 pxwidth = /所要畫坐標(biāo)的像素范圍 (float)(width - 100) / (_fXBegin - _fXEnd) * (_fXBeginGO - _fXEndGO); pxLine = pxwidth / linesNum; /每段坐標(biāo)線間隔 pxGO = /所要畫坐標(biāo)的起點(diǎn)像素位置 (_fXEndGO - _fXBegin) / (_fXEnd - _fXBegin) * (width - 100) + 50;/回到目錄4.1.4  子標(biāo)尺線的選擇性顯示根據(jù)每段坐標(biāo)線間隔,可以設(shè)計出符合用戶視覺的子標(biāo)尺線,如下圖所示:

37、圖 43子標(biāo)尺線的選擇性顯示A圖 44子標(biāo)尺線的選擇性顯示B 當(dāng)波形顯示控件被拉伸到足夠大的時候,子標(biāo)尺線能夠選擇性的顯示。具體設(shè)計可以通過使用坐標(biāo)標(biāo)尺繪制時定義的每段坐標(biāo)線間隔pxLine來實(shí)現(xiàn)。本課題的坐標(biāo)設(shè)計為可以顯示三層坐標(biāo)線,兩層坐標(biāo)值。當(dāng)pxLine小于等于250時候,畫第一層坐標(biāo),顯示坐標(biāo)值;畫第二層坐標(biāo),第一層坐標(biāo)的基礎(chǔ)上5等分,前提是間距大于10px,若間距大于50px則顯示坐標(biāo)值。即當(dāng)pxLine大于250,則將pxLine五等分,繪制第二層坐標(biāo)線以及坐標(biāo)值,當(dāng)pxLine只大于50,則將pxLine五等分,繪制第二層坐標(biāo)線。繼續(xù)判斷若此時pxLine大于50,則

38、將pxLine五等分,繪制第三層坐標(biāo)線,若pxLine只大于20,則將pxLine二等分,并繪制第三層坐標(biāo)線。if (pxLine <= 250) currentI = (int)linesNum + 1; showTextT = (decimal)_fXEndGO; currentDraw = pxGO; for (int i = 0; i < currentI; i+) if (currentDraw > 50 && currentDraw < width - 50) Grap.DrawLine(pe, currentDraw, 0, current

39、Draw, 6); /畫坐標(biāo)線 Grap.DrawString /畫坐標(biāo)值 (showTextT.ToString(), fo, brushString, currentDraw, 6, format); showTextT -= (decimal)linesQuan; /更新要畫的坐標(biāo)值 currentDraw -= pxLine; /更新坐標(biāo)線和坐標(biāo)值的位置 /回到目錄4.2  數(shù)據(jù)點(diǎn)的描繪4.2.1  數(shù)據(jù)值轉(zhuǎn)換為坐標(biāo)值在數(shù)據(jù)存儲結(jié)構(gòu)設(shè)計的時候,通過兩個List<List<float>>獲得的是要顯示數(shù)據(jù)的數(shù)據(jù)值,而不是最后描繪到波形顯示控件上

40、的具體坐標(biāo)值,因此需要從數(shù)據(jù)值到坐標(biāo)值的轉(zhuǎn)換。并將轉(zhuǎn)換后得到的坐標(biāo)值存儲到成員變量中:private List<PointF> _listDrawPoints = new List<PointF>();默認(rèn)情況下,GDI+是以像素單位來繪圖的,初始情況下從控件的左上角沿X軸向右增長,沿Y軸向下增長,并且左上角第一個像素的坐標(biāo)為(0,0)。為了計算方便,將坐標(biāo)系變換為以左下角為零點(diǎn),從左下角沿X軸向右增長,沿Y軸向上增長。然后設(shè)計一個函數(shù),遍歷要畫的數(shù)據(jù)集合,并轉(zhuǎn)換為坐標(biāo)值:private bool _changeToDrawPoints( int index, /要遍歷

41、的數(shù)據(jù)集合的編號 ref List<PointF> listDrawPoints, /轉(zhuǎn)后后的坐標(biāo)集合 int width, /畫布像素寬度 int height, /畫布像素高度 ); 同時定義了一個私有成員變量,表示坐標(biāo)精確度:private float _fAccuracy = 0.05f;若坐標(biāo)起始和結(jié)束值之差小于精度范圍,則函數(shù)返回false,這樣防止出現(xiàn)數(shù)據(jù)轉(zhuǎn)換的過程中出現(xiàn)數(shù)據(jù)溢出: if (_fXEnd - _fXBegin) < _fAccuracy | (_fYEnd - _fYBegin) < _fAccuracy) return fals

42、e;在遍歷數(shù)據(jù)的時候,出現(xiàn)非數(shù)字值則跳過:if (float.IsNaN(_listXindexi) | float.IsNaN(_listYindexi) continue;數(shù)據(jù)值根據(jù)當(dāng)前波形顯示控件大小和坐標(biāo)范圍轉(zhuǎn)換為坐標(biāo)值: currentPointF.X = (_listXindexi - _fXBegin) * (width - 1) / (_fXEnd - _fXBegin); currentPointF.Y = (_listYindexi - _fYBegin) * (height - 1) / (_fYEnd - _fYBegin); listDrawPoints.Add(cu

43、rrentPointF);回到目錄 4.2.2  溢出坐標(biāo)范圍的數(shù)據(jù)點(diǎn)的處理當(dāng)有要繪制的數(shù)據(jù)值超出的波形顯示控件當(dāng)前坐標(biāo)的表示范圍,若要實(shí)現(xiàn)自動調(diào)整坐標(biāo)范圍的功能,首先要實(shí)現(xiàn)坐標(biāo)端點(diǎn)的自動改變。因?yàn)楸菊n題設(shè)計的坐標(biāo)為雙坐標(biāo)模式,因此可以添加一個函數(shù)來實(shí)現(xiàn),根據(jù)溢出坐標(biāo)范圍的浮點(diǎn)數(shù),改變X軸的坐標(biāo)標(biāo)定權(quán)值和坐標(biāo)標(biāo)定值:private void _changXBegionOrEndGO( float m, /溢出坐標(biāo)范圍的浮點(diǎn)數(shù) bool isL /是否從左邊溢出 );同樣的還有Y軸對應(yīng)的函數(shù):private void _changYBegionOrEndGO(float m,

44、 bool isL);函數(shù)內(nèi)先通過_getQuan函數(shù)獲得溢出點(diǎn)的權(quán),并根據(jù)該權(quán)值修改對應(yīng)坐標(biāo)軸的起點(diǎn)坐標(biāo)權(quán)值和結(jié)束坐標(biāo)權(quán)值,同時控制權(quán)差在10倍以內(nèi),然后根據(jù)新的權(quán)值修改坐標(biāo)的標(biāo)定值。具體設(shè)計如下:float quan = _getQuan(m);if(isL) if (quan < _fXQuanEndGO) _fXQuanBeginGO = _fXQuanEndGO / 10f; else if (quan > _fXQuanEndGO) _fXQuanBeginGO = quan; _fXQuanEndGO = _fXQuanBeginGO / 10f; else _fXQ

45、uanBeginGO = _fXQuanEndGO; if (m <= _fXQuanBeginGO && m >= -_fXQuanBeginGO) _fXBeginGO = -_fXQuanBeginGO; else _fXBeginGO = (int)(m / _fXQuanBeginGO) - 1) * _fXQuanBeginGO;else 實(shí)際使用過程中,在pictureBoxGraph的OnPaint消息響應(yīng)函數(shù)中在判斷繪圖模式為放大模式或坐標(biāo)自動調(diào)整模式的時候,可以調(diào)用該函數(shù)以實(shí)現(xiàn)相應(yīng)的功能?;氐侥夸?.2.3  遍歷所有數(shù)據(jù)線并繪制出繪制

46、數(shù)據(jù)線的工作在pictureBoxGraph的OnPaint消息中完成。在該函數(shù)根據(jù)繪圖模式調(diào)整完坐標(biāo)范圍并更新pictureBoxBottom和pictureBoxLeft的坐標(biāo)標(biāo)尺的顯示后,開始遍歷所有要顯示的數(shù)據(jù)并繪制出。每繪制List<List<float>>中的一條數(shù)據(jù)集合,都先調(diào)用原先設(shè)計好的數(shù)據(jù)值轉(zhuǎn)坐標(biāo)值函數(shù)_changeToDrawPoints,若操作成功,則獲取當(dāng)前要繪制的數(shù)據(jù)集合的顏色、線寬、連接點(diǎn)樣式、起始線帽,并加載到當(dāng)前畫筆中。for (int i = 0; i < _listX.Count; i+) _listDrawPoints.Cl

47、ear(); if (!_changeToDrawPoints(i, ref _listDrawPoints, width, height) continue; pe.Color = _listColori; /裝載顏色 pe.Width = _listWidthi; /裝載寬度 pe.LineJoin = _listLineJoini; /裝載連接點(diǎn) pe.StartCap = _listLineCapi; /裝載起始線帽然后通過判斷繪圖樣式(線、點(diǎn)、條形圖),繪制出圖形。注意在繪制線條的時候,設(shè)置連接點(diǎn)指定成斜角的連接,這樣可以防止線寬在大于1的情況下導(dǎo)致的轉(zhuǎn)折點(diǎn)不精確的問題:if (_l

48、istDrawStylei = DrawStyle.Line) /繪制線 f (_listDrawPoints.Count = 1) continue; pe.LineJoin = LineJoin.Bevel; Grap.DrawLines(pe, _listDrawPoints.ToArray();由上面代碼可知,實(shí)際使用控件時若繪圖樣式設(shè)置為線,則傳入的線條連接點(diǎn)參數(shù)是不會被使用的。繪制點(diǎn)和條形圖如下所示:else if (_listDrawStylei = DrawStyle.dot) /繪制方形點(diǎn) foreach (PointF points in _listDrawPoints)

49、Grap.DrawRectangle(pe, points.X, points.Y, 1, 1); else foreach (PointF points in _listDrawPoints) /繪制條形線 Grap.DrawLine(pe, points.X, points.Y, points.X, 0); 回到目錄4.3  波形顯示區(qū)域網(wǎng)格的實(shí)現(xiàn)4.3.1  網(wǎng)格相關(guān)的成員變量網(wǎng)格的顯示是同顯示的坐標(biāo)標(biāo)尺的標(biāo)尺線相對應(yīng)的,因此在繪制坐標(biāo)標(biāo)尺的同時,可以保存繪制標(biāo)尺的狀態(tài),然后在pictureBoxGraph中繪制數(shù)據(jù)點(diǎn)之前,將網(wǎng)格繪制到pictureBoxGraph中

50、。因此需要的成員變量如下:private bool _bXLinesLBegin; /X軸網(wǎng)格線是否從左開始畫private bool _bYLinesLBegin; /Y軸網(wǎng)格線是否從下開始畫private float _fXpxGO; /所要畫X軸坐標(biāo)的起點(diǎn)像素位置private float _fYpxGO; /所要畫Y軸坐標(biāo)的起點(diǎn)像素位置private float _fXLinesShowFirst = 0; /X軸第一層網(wǎng)格線間隔private float _fXLinesShowSecond = 0; /X軸第二層網(wǎng)格線間隔private float _fXLinesShowThir

51、d = 0; /X軸第三層網(wǎng)格線間隔private float _fYLinesShowFirst = 0; /Y軸第一層網(wǎng)格線間隔private float _fYLinesShowSecond = 0; /Y軸第二層網(wǎng)格線間隔private float _fYLinesShowThird = 0; /Y軸第三層網(wǎng)格線間隔當(dāng)網(wǎng)格線間隔為0的時候,則不畫出該層的網(wǎng)格線。為了增強(qiáng)用戶體驗(yàn),將各層的網(wǎng)格線使用不同的透明度繪制出:pe.Color = Color.FromArgb(_iLineShowColorAlpha, _iLineShowColor);pe.Color = Color.FromArgb(_iLineShowColorAlpha / 2, _iLineShowColor);pe.Color =

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論