轉(zhuǎn)帖|其它|編輯:郝浩|2010-09-10 11:46:07.000|閱讀 817 次
概述:組合框是組成Windows窗口常見(jiàn)的控件之一,Windows程序員在應(yīng)用軟件開發(fā)中經(jīng)常要用到組合框。但隨微軟開發(fā)工具語(yǔ)言(如C/C++/C#/VB/VF)提供的標(biāo)準(zhǔn)組合框都是同一面孔:組合框中每一項(xiàng)都是字符串,看起來(lái)有點(diǎn)灰頭土臉,不那么賞心悅目。今天我們就來(lái)給組合框美容一下,使組合框中每一項(xiàng)都帶有個(gè)性,組合框中每一項(xiàng)即可以讓字符串格式變化多樣,也可以使每一項(xiàng)都帶有各種圖形,同樣也可以讓每一項(xiàng)都帶有圖像等等。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
組合框是組成Windows窗口常見(jiàn)的控件之一,Windows程序員在應(yīng)用軟件開發(fā)中經(jīng)常要用到組合框。但隨微軟開發(fā)工具語(yǔ)言(如C/C++/C#/VB/VF)提供的標(biāo)準(zhǔn)組合框都是同一面孔:組合框中每一項(xiàng)都是字符串,看起來(lái)有點(diǎn)灰頭土臉,不那么賞心悅目。
今天我們就來(lái)給組合框美容一下,使組合框中每一項(xiàng)都帶有個(gè)性,組合框中每一項(xiàng)即可以讓字符串格式變化多樣,也可以使每一項(xiàng)都帶有各種圖形,同樣也可以讓每一項(xiàng)都帶有圖像等等。
例1:本例中我們?cè)谝粋€(gè)表單上創(chuàng)建三個(gè)組合框,從上到下名字分別為comboBox1~comboBox3,通過(guò)編程分別讓它們的組合框條目字符串格式發(fā)生變化、每項(xiàng)前都有圖形、每項(xiàng)前都有圖像。
第一步:建立項(xiàng)目
建立一名為TestComboBox的Windows應(yīng)用程序(注:應(yīng)用程序名可以隨意)。
第二步:界面設(shè)計(jì)
本例界面比較簡(jiǎn)單,三個(gè)label,三個(gè)組合框(如圖2所示,從上到上組合框名依次為comboBox1、comboBox2、comboBox3),一個(gè)imageList控件(當(dāng)然表單上看不到,在表單設(shè)計(jì)圖的下方)
第三步:控件屬性設(shè)置
(1)把三個(gè)label的Text屬性按圖2設(shè)置;
(2)三個(gè)comboBox的屬性進(jìn)行如下設(shè)置:
DrawMode:OwnerDrawFixed;
DropDownStyle:DropDownList;
注:這兩個(gè)屬性只有如此設(shè)置才能保證我們對(duì)組合框進(jìn)行個(gè)性化改造,否則的話無(wú)論你的程序?qū)懙枚嗝春茫瑯舆€是"灰頭土臉,不是那么賞心悅目。
(3)通過(guò)imageList1的Item屬性向imageList增添幾個(gè)圖像。
第四步:編程
說(shuō)明:當(dāng)我們通過(guò)組合框的Add方法向組合框添加item時(shí),都會(huì)發(fā)生組合框的DrawItem事件處理函數(shù)來(lái)畫組合框item,因此如果我們想創(chuàng)建個(gè)性化的組合框只有在DrawItem事件處理函數(shù)中做文章了。在編程之前我們需要了解如下的基礎(chǔ)知識(shí)。
(1)在組合框條目中顯示文本時(shí)都是利用grphics類的DrawString函數(shù),此函數(shù)有多個(gè)變體,現(xiàn)把此函數(shù)各種形式簡(jiǎn)介如下:
①public void DrawString(string, Font, Brush, PointF);
在指定位置并且用指定的 Brush 和 Font 對(duì)象繪制指定的文本字符串。
②public void DrawString(string, Font, Brush, RectangleF);
在指定矩形并且用指定的 Brush 和 Font 對(duì)象繪制指定的文本字符串。
③public void DrawString(string, Font, Brush, PointF, StringFormat);
使用指定 StringFormat 對(duì)象的格式化屬性,用指定的 Brush 和 Font 對(duì)象在指定的位置繪制指定的文本字符串。
④public void DrawString(string, Font, Brush, RectangleF, StringFormat);
使用指定 StringFormat 對(duì)象的格式化屬性,用指定的 Brush 和 Font 對(duì)象在指定的矩形繪制指定的文本字符串。
⑤public void DrawString(string, Font, Brush, float, float);
在指定位置并且用指定的 Brush 和 Font 對(duì)象繪制指定的文本字符串。
⑥public void DrawString(string, Font, Brush, float, float, StringFormat);
使用指定 StringFormat 對(duì)象的格式化屬性,用指定的 Brush 和 Font 對(duì)象在指定的位置繪制指定的文本字符串。
在本例中我們注意使用第④種。
(2)在組合框畫矩形時(shí)大都使用graphics類的FillRectangle()函數(shù),本例中我們所用的格式如下:
FillRectangle(brush_name,rectange);
(3)comboBox1~comboBox3的DrawItem事件處理程序接收一個(gè) DrawItemEventArgs 類型的參數(shù),它包含與此事件相關(guān)的數(shù)據(jù)。下列 DrawItemEventArgs 屬性提供特定于此事件的信息。
BackColor:獲取所繪制的項(xiàng)的背景色。
Bounds:獲取表示所繪制項(xiàng)的邊界的矩形。
Font:獲取分配給所繪制項(xiàng)的字符串格式。
ForeColor: 獲取所繪制項(xiàng)的前景色。
Graphics:獲取要在其上繪制項(xiàng)的圖形表面。
Index:獲取所繪制項(xiàng)的索引值。
State:獲取所繪制項(xiàng)的狀態(tài)。
有了以上的"基礎(chǔ)知識(shí)"我們開始編程了。因?yàn)槲覀兿朐赾omboBox1改變字符串格式,在comboBox2中改變每項(xiàng)前的圖形顏色顏色,所以我們需要?jiǎng)?chuàng)建多種字符串格式、多種畫刷。因此我們必須建立兩個(gè)ArrayList類型的數(shù)組來(lái)保存我們創(chuàng)建的字符串格式與畫刷,于是在類的前面添加如下兩句:
ArrayList brushArray = new ArrayList() ;
ArrayList fontArray = new ArrayList() ;
(4)我們什么時(shí)候創(chuàng)建字符串格式組、畫刷組比較合適呢?當(dāng)然要在畫組合框之前了,不然的話如何用?因此只有在Form1_Load事件中前部創(chuàng)建字符串格式、畫刷了。Form1_Load代碼如下:
private void Form1_Load(object sender, System.EventArgs e)
{
//創(chuàng)建字符串格式
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));
//創(chuàng)建畫刷
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,注意它要調(diào)用comboBox1_DrawItem來(lái)畫
comboBox1.Items.Add("中國(guó)");
comboBox1.Items.Add("巴西");
comboBox1.Items.Add("哥斯達(dá)黎加");
comboBox1.Items.Add("土耳其");
comboBox1.Items.Add("韓國(guó)");
comboBox1.Items.Add("日本");
//畫comboBox2,注意它要調(diào)用comboBox2_DrawItem來(lái)畫
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,注意它要調(diào)用comboBox3_DrawItem來(lái)畫
comboBox3.Items.Add("趙微");
comboBox3.Items.Add("舒淇");
}
問(wèn)題:僅從Form_Load的代碼來(lái)看三個(gè)comboBox,應(yīng)該差別不大,因?yàn)樗鼈兊拇a幾乎完全一模一樣,實(shí)際情況如何呢?我們還是來(lái)看看最終的運(yùn)行界面吧
我們看看comboBox1的DrawItem事件處理函數(shù),其代碼如下:
private void comboBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
//確定畫布
Graphics g = e.Graphics ;
//繪制區(qū)域
Rectangle r = e.Bounds ;
Font fn = null ;
if ( e.Index >= 0 )
{
//設(shè)置字體、字符串格式、對(duì)齊方式
fn = (Font)fontArray[e.Index];
string s = (string)comboBox1.Items[e.Index];
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
//根據(jù)不同的狀態(tài)用不同的顏色表示
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();
}
}
}
再來(lái)看看comboBox2的DrawItem事件處理函數(shù),其代碼如下:
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics ;
Rectangle r = e.Bounds ;
if ( e.Index >= 0 )
{
//設(shè)置字符串前矩形塊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);
//設(shè)置字符串的格式
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);
//繪制取得焦點(diǎn)時(shí)的虛線框
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事件處理函數(shù),其源代碼如下:
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);
//顯示取得焦點(diǎn)時(shí)的虛線框
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();
}
}
}
看到這兒,聰明的讀者也許會(huì)說(shuō),其實(shí)為組合框"變臉"很簡(jiǎn)單,只要修改各個(gè)組合框的DrawItem事件處理函數(shù)即可。如果你能明白這一點(diǎn),我這篇文章的目的就達(dá)到了。
在本文快要結(jié)果之前我們還是來(lái)看看應(yīng)用程序入口函數(shù)的代碼:
static void Main()
{
Form frm=new Form1();
frm.ShowDialog();
}
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載