欢迎光临
我们一直在努力

OwnerDraw in C#-.NET教程,C#语言

建站超值云服务器,限时71元/月

对于像combobox等控件,我们可以通过设置它们的drawmode特性(attribute)来对其进行绘制.

为了方便起见,我们先定义一个类stringcolorobject(这与ownerdraw本身没有关系,只是针对这里要使用到的combobox而特意书写的一个类.类的命名得益于quickstart).这个类本身很简单:

using system.drawing;

namespace ownerdrawsample

{

public class stringcolorobject

{

//field to hold the string representing the color

private string colorrepresent;

//field to hold the actually color,the value of the string colorrepresent

private color color;

//the constructor

//takes 2 parameters, the color representation and the color itself

public stringcolorobject(string colorrepresent,color color)

{

this.colorrepresent = colorrepresent;

this.color = color;

}

//some attributes

public string colorrepresentation

{

get

{

return this.colorrepresent;

}

//only getter,no setter

}

public color color

{

get

{

return this.color;

}

//only getter,no setter

}

//override the tostring method in system.object

public override string tostring()

{

return this.colorrepresent;

}

//override the gethashcode method

public override int gethashcode()

{

//return the key field’s hash code

return this.color.gethashcode();

}

//override the equals method

public override bool equals(object obj)

{

if(!(obj is stringcolorobject))

return false;

return this.color.equals(((stringcolorobject)obj).color);

}

}

}

建立一个windows application,并从工具箱中拖拽一个combobox到form中去,并命名为cmbcolors然后在form的构造函数中添加:

//

// todo: 在initializecomponent调用后添加任何构造函数代码

//

this.fillcomboxcolor(this.cmbcolors);

this.cmbcolors.selectedindex = 0;

其中,fillcomboxcolor(combobox )为自定义函数,它用来填充参数指定的combobox对象.它的实现为:

private void fillcomboxcolor(combobox cmb){

cmb.items.addrange(new object[]{

new stringcolorobject("黑色(black)",color.black),

new stringcolorobject("蓝色(blue)",color.blue),

new stringcolorobject("深红(dark red)",color.darkred),

new stringcolorobject("绿色(green)",color.green),

//……

});

}

上面只是一些准备工作,ownerdraw的实际工作现在才刚刚开始.将combobox对象cmbcolors的drawmode设置为ownerdrawfixed(或是ownerdrawvariable,这里设置为ownerdrawfixed模式).附带说明一下:drawmode可以取normal,ownerdrawfixed和ownerdrawvariable三者之一.其中,normal模式表示控件由操作系统绘制,并且元素的大小都相等;ownerdrawfixed模式表示控件由手工绘制,并且元素的大小都相等;ownerdrawvariable则是表示控件由手工绘制,并且元素的大小可以不相等。

下面开始ownerdraw的核心部分:

1) 撰写控件的measureitem事件

当要显示combobox的某一项(item)的时候[即是单击combobox的下拉按钮时],这个事件会被首先唤起。它用来测量item的长度,宽度信息。例如:

//注册事件

this.cmbcolor.measureitem += new measureitemeventhandler(this.cmbcolor_measureitem);

//实现cmbcolor_measureitem—测量combobox的每一个item

private void cmbcolor_measureitem(object sender, system.windows.forms.measureitemeventargs e)

{

//一般来说,这里需要设置的是measureitemeventargs对象e的itemheight属性和itemwidth属性

combobox cmb = (combobox)sender;

e.itemheight = cmb.itemheight;//当然,你可以写e.itemheight = 20;

//不过对于ownerdrawfixed模式,这个函数好像都是多余.(对于combobox而言如此)

//why?????????????more work is essential.

}

2) 撰写控件的drawitem事件

combobox中的项的绘制任务将在drawitem事件中完成.类似地,先注册该事件,然后再添加适当的代码完成对事件的响应:

//注册事件

this.cmbcolor.drawitem += new

drawitemeventhandler(this.cmbcolor_drawitem);

//绘制item

private void cmbcolor_drawitem(object sender, system.windows.forms.drawitemeventargs e)

{

combobox cmb = (combobox)sender;

if(cmb == null) return;

int index = e.index; //获取要绘制的item的index(索引)

if(index == -1) return;

//如果item被选择,绘制正确的背景色

e.drawbackground();

e.drawfocusrectangle();//因为item被选择,绘制焦点矩形

graphics g = e.graphics;

//根据item的index获取对应的颜色

color c = ((stringcolorobject)cmbcolor.items[index]).color;

rectangle rectcolor = e.bounds;//获取包围item的边框,并存储在rectcolor中

//将rectcolor做适当变换,这不会影响到e.bounds本身

rectcolor.offset(2,2);//右移2,下移2

rectcolor.width = 20;//宽度设置为20

rectcolor.height -= 4;//高度减4

g.drawrectangle(new pen(c),rectcolor);//绘制rectcolor代表的矩形,即是在图中看到的item左边的矩形部分

//再次将rectcolor做变换,并填充之

rectcolor.offset(2,2);

rectcolor.width = 17;//要注意,在c#中绘制和填充

rectcolor.height -= 3;// 对最后一个象素点的不同处理方式

g.fillrectangle(new solidbrush(c),rectcolor);//填充rectcolor矩形,这个矩形就是在图中看到的item左边的那个被填充的矩形

g.drawstring(((stringcolorobject)cmbcolor.items[index]).tostring(),

this.font,new solidbrush(c),e.bounds.left + 25,e.bounds.top);

//绘制字符串

}

这段程序会运行得很好.为了能够读懂程序,你得知道如下的一些概念:

1). e.index measureitemeventargs对象的index属性表达的意思是欲绘制的item的索引值之义.对于上面的例子,黑色(black),蓝色(blue)…分别对应着index的0,1…(这种说法不是很严密,但易于接受.比较严密的说法是,stringcolorobject对象对应着index…).

2). e.graphics 这是要在item上绘制的graphics对象.有了它,就能在item上实现图形的绘制了.

3). e.bounds 这是要绘制的item的边界矩形.

知道了这些概念,就不难理解上面drawitem完成的操作以及为什么会那样去完成。

对于menuitem的手工绘制,你要做的事和上面差不多.不同的是,你需要将其ownerdraw由默认的false设置为true.然后再measureitem,drawitem.如果你亲身实践,你会发现如果你不注册measureitem并辅以相应代码,你不会看到那个menuitem.

—the end

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » OwnerDraw in C#-.NET教程,C#语言
分享到: 更多 (0)

相关推荐

  • 暂无文章