轉帖|其它|編輯:郝浩|2010-09-10 11:46:07.000|閱讀 817 次
概述:組合框是組成Windows窗口常見的控件之一,Windows程序員在應用軟件開發中經常要用到組合框。但隨微軟開發工具語言(如C/C++/C#/VB/VF)提供的標準組合框都是同一面孔:組合框中每一項都是字符串,看起來有點灰頭土臉,不那么賞心悅目。今天我們就來給組合框美容一下,使組合框中每一項都帶有個性,組合框中每一項即可以讓字符串格式變化多樣,也可以使每一項都帶有各種圖形,同樣也可以讓每一項都帶有圖像等等。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
組合框是組成Windows窗口常見的控件之一,Windows程序員在應用軟件開發中經常要用到組合框。但隨微軟開發工具語言(如C/C++/C#/VB/VF)提供的標準組合框都是同一面孔:組合框中每一項都是字符串,看起來有點灰頭土臉,不那么賞心悅目。
今天我們就來給組合框美容一下,使組合框中每一項都帶有個性,組合框中每一項即可以讓字符串格式變化多樣,也可以使每一項都帶有各種圖形,同樣也可以讓每一項都帶有圖像等等。
例1:本例中我們在一個表單上創建三個組合框,從上到下名字分別為comboBox1~comboBox3,通過編程分別讓它們的組合框條目字符串格式發生變化、每項前都有圖形、每項前都有圖像。
第一步:建立項目
建立一名為TestComboBox的Windows應用程序(注:應用程序名可以隨意)。
第二步:界面設計
本例界面比較簡單,三個label,三個組合框(如圖2所示,從上到上組合框名依次為comboBox1、comboBox2、comboBox3),一個imageList控件(當然表單上看不到,在表單設計圖的下方)
第三步:控件屬性設置
(1)把三個label的Text屬性按圖2設置;
(2)三個comboBox的屬性進行如下設置:
DrawMode:OwnerDrawFixed;
DropDownStyle:DropDownList;
注:這兩個屬性只有如此設置才能保證我們對組合框進行個性化改造,否則的話無論你的程序寫得多么好,同樣還是"灰頭土臉,不是那么賞心悅目。
(3)通過imageList1的Item屬性向imageList增添幾個圖像。
第四步:編程
說明:當我們通過組合框的Add方法向組合框添加item時,都會發生組合框的DrawItem事件處理函數來畫組合框item,因此如果我們想創建個性化的組合框只有在DrawItem事件處理函數中做文章了。在編程之前我們需要了解如下的基礎知識。
(1)在組合框條目中顯示文本時都是利用grphics類的DrawString函數,此函數有多個變體,現把此函數各種形式簡介如下:
①public void DrawString(string, Font, Brush, PointF);
在指定位置并且用指定的 Brush 和 Font 對象繪制指定的文本字符串。
②public void DrawString(string, Font, Brush, RectangleF);
在指定矩形并且用指定的 Brush 和 Font 對象繪制指定的文本字符串。
③public void DrawString(string, Font, Brush, PointF, StringFormat);
使用指定 StringFormat 對象的格式化屬性,用指定的 Brush 和 Font 對象在指定的位置繪制指定的文本字符串。
④public void DrawString(string, Font, Brush, RectangleF, StringFormat);
使用指定 StringFormat 對象的格式化屬性,用指定的 Brush 和 Font 對象在指定的矩形繪制指定的文本字符串。
⑤public void DrawString(string, Font, Brush, float, float);
在指定位置并且用指定的 Brush 和 Font 對象繪制指定的文本字符串。
⑥public void DrawString(string, Font, Brush, float, float, StringFormat);
使用指定 StringFormat 對象的格式化屬性,用指定的 Brush 和 Font 對象在指定的位置繪制指定的文本字符串。
在本例中我們注意使用第④種。
(2)在組合框畫矩形時大都使用graphics類的FillRectangle()函數,本例中我們所用的格式如下:
FillRectangle(brush_name,rectange);
(3)comboBox1~comboBox3的DrawItem事件處理程序接收一個 DrawItemEventArgs 類型的參數,它包含與此事件相關的數據。下列 DrawItemEventArgs 屬性提供特定于此事件的信息。
BackColor:獲取所繪制的項的背景色。
Bounds:獲取表示所繪制項的邊界的矩形。
Font:獲取分配給所繪制項的字符串格式。
ForeColor: 獲取所繪制項的前景色。
Graphics:獲取要在其上繪制項的圖形表面。
Index:獲取所繪制項的索引值。
State:獲取所繪制項的狀態。
有了以上的"基礎知識"我們開始編程了。因為我們想在comboBox1改變字符串格式,在comboBox2中改變每項前的圖形顏色顏色,所以我們需要創建多種字符串格式、多種畫刷。因此我們必須建立兩個ArrayList類型的數組來保存我們創建的字符串格式與畫刷,于是在類的前面添加如下兩句:
ArrayList brushArray = new ArrayList() ;
ArrayList fontArray = new ArrayList() ;
(4)我們什么時候創建字符串格式組、畫刷組比較合適呢?當然要在畫組合框之前了,不然的話如何用?因此只有在Form1_Load事件中前部創建字符串格式、畫刷了。Form1_Load代碼如下:
private void Form1_Load(object sender, System.EventArgs e)
{
//創建字符串格式
fontArray .Add(new Font("Ariel" , 8 , FontStyle.Bold ));
fontArray .Add(new Font("Courier" , 8 , FontStyle.Italic));
fontArray .Add(new Font("Veranda" , 8 , FontStyle.Bold));
fontArray .Add(new Font("System" , 8 , FontStyle.Strikeout));
fontArray .Add(new Font("Century SchoolBook" , 8 , FontStyle.Underline));
fontArray .Add(new Font("Helevctia" , 8 , FontStyle.Italic));
//創建畫刷
brushArray.Add(new SolidBrush(Color.Red));
brushArray.Add(new SolidBrush(Color.Blue));
brushArray.Add(new SolidBrush(Color.Green));
brushArray.Add(new SolidBrush(Color.Yellow));
brushArray.Add(new SolidBrush(Color.Black));
brushArray.Add(new SolidBrush(Color.Azure));
brushArray.Add(new SolidBrush(Color.Firebrick));
brushArray.Add(new SolidBrush(Color.DarkMagenta));
brushArray.Add(new SolidBrush(Color.DarkTurquoise));
brushArray.Add(new SolidBrush(Color.Khaki));
//畫comboBox1,注意它要調用comboBox1_DrawItem來畫
comboBox1.Items.Add("中國");
comboBox1.Items.Add("巴西");
comboBox1.Items.Add("哥斯達黎加");
comboBox1.Items.Add("土耳其");
comboBox1.Items.Add("韓國");
comboBox1.Items.Add("日本");
//畫comboBox2,注意它要調用comboBox2_DrawItem來畫
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
//畫comboBox3,注意它要調用comboBox3_DrawItem來畫
comboBox3.Items.Add("趙微");
comboBox3.Items.Add("舒淇");
}
問題:僅從Form_Load的代碼來看三個comboBox,應該差別不大,因為它們的代碼幾乎完全一模一樣,實際情況如何呢?我們還是來看看最終的運行界面吧
我們看看comboBox1的DrawItem事件處理函數,其代碼如下:
private void comboBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
//確定畫布
Graphics g = e.Graphics ;
//繪制區域
Rectangle r = e.Bounds ;
Font fn = null ;
if ( e.Index >= 0 )
{
//設置字體、字符串格式、對齊方式
fn = (Font)fontArray[e.Index];
string s = (string)comboBox1.Items[e.Index];
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
//根據不同的狀態用不同的顏色表示
if ( e.State == ( DrawItemState.NoAccelerator | DrawItemState.NoFocusRect))
{
e.Graphics.FillRectangle(new SolidBrush(Color.Red) , r);
e.Graphics.DrawString( s , fn , new SolidBrush(Color.Black), r ,sf);
e.DrawFocusRectangle();
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.LightBlue) , r);
e.Graphics.DrawString( s , fn , new SolidBrush(Color.Red), r ,sf);
e.DrawFocusRectangle();
}
}
}
再來看看comboBox2的DrawItem事件處理函數,其代碼如下:
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics ;
Rectangle r = e.Bounds ;
if ( e.Index >= 0 )
{
//設置字符串前矩形塊rd的大小
Rectangle rd = r ;
rd.Width = rd.Left + 20 ;
Rectangle rt = r ;
r.X = rd.Right ;
//用不同的顏色畫矩形塊
SolidBrush b = (SolidBrush)brushArray[e.Index];
g.FillRectangle(b , rd);
//設置字符串的格式
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
if ( e.State == ( DrawItemState.NoAccelerator | DrawItemState.NoFocusRect))
{
//字符串背景
e.Graphics.FillRectangle(new SolidBrush(Color.White) , r);
//顯示字符串
e.Graphics.DrawString( b.Color.Name, new Font("Ariel" ,8 , FontStyle.Bold ) , new SolidBrush(Color.Black), r ,sf);
//繪制取得焦點時的虛線框
e.DrawFocusRectangle();
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.LightBlue) , r);
e.Graphics.DrawString( b.Color.Name, new Font("Veranda" , 8 , FontStyle.Bold ) , new SolidBrush(Color.Red), r ,sf);
e.DrawFocusRectangle();
}
}
}
最后我們看看comboBox3的DrawItem事件處理函數,其源代碼如下:
private void comboBox3_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics ;
Rectangle r = e.Bounds ;
Size imageSize = imageList1.ImageSize;
Font fn = null ;
if ( e.Index >= 0 )
{
fn = (Font)fontArray[0];
string s = (string)comboBox3.Items[e.Index];
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
if ( e.State == ( DrawItemState.NoAccelerator | DrawItemState.NoFocusRect))
{
//畫條目背景
e.Graphics.FillRectangle(new SolidBrush(Color.Red) , r);
//繪制圖像
imageList1.Draw(e.Graphics, r.Left, r.Top,e.Index);
//顯示字符串
e.Graphics.DrawString( s , fn , new SolidBrush(Color.Black), r.Left+imageSize.Width ,r.Top);
//顯示取得焦點時的虛線框
e.DrawFocusRectangle();
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.LightBlue) , r);
imageList1.Draw(e.Graphics, r.Left, r.Top,e.Index);
e.Graphics.DrawString( s , fn , new SolidBrush(Color.Black),r.Left+imageSize.Width ,r.Top);
e.DrawFocusRectangle();
}
}
}
看到這兒,聰明的讀者也許會說,其實為組合框"變臉"很簡單,只要修改各個組合框的DrawItem事件處理函數即可。如果你能明白這一點,我這篇文章的目的就達到了。
在本文快要結果之前我們還是來看看應用程序入口函數的代碼:
static void Main()
{
Form frm=new Form1();
frm.ShowDialog();
}
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:網絡轉載