您的位置:首页 > 编程语言 > C#

C# 关于控件的z-order(Z轴次序)属性(By dlm)

2014-11-23 16:57 288 查看
转自豆丁

最近在C#的windows form编程中,涉及到了控件的z-order(Z轴次序)的属性。它来源于三维空间的概念,x和y分别代表屏幕所在平面上的水平坐标和垂直坐标,而z轴则是垂直于屏幕的。在此根据<<Programming Microsoft Window with c#.net>>书籍中的相关内容及自己的理解做一个总结,并实现了一个应用实例,即由按钮和列表控件一起构成的分栏框。

对于属于同一父控件的一组控件,z-order的作用表现在两方面:一是控件组中每个控件在同一位置时的叠加顺序;二是当几个控件停靠在父控件的同一边缘时的堆积顺序。z-order的初始值是根据你设置每个控件的parent属性值的顺序或者将一个控件加入到一个控件集合的顺序来决定的。具体如下:

若一个控件是在z轴最上层,则它具有以下属性:

l 它第一个被设置parent属性或第一个被加入到控件集合中;

l 它在控件集合中的index即索引值为0;

l 它在其它所有控件的最上层,可以接收到鼠标消息;

l 当多个控件停靠到父控件的同一边缘时,它最靠近客户区的中间;

若一个控件是在z轴最下层,则它具有以下属性:

l 它最后一个被设置parent属性或最后一个被加入到控件集合中;

l 它在控件集合中的index即索引值为(Controls.Count-1,即控件组中的控件数目减1);

l 它在其它所有控件的最下层;

l 当多个控件停靠到父控件的同一边缘时,它停靠在此边缘上;

可以查看相应的Windows 窗体设计器生成的代码,可以看到最靠近客户区中间的控件是最早被加入到控件集合中的,而停靠在边缘的控件则是最后被加入到控件集合中的。明白了以上基础原理后,即可调用控件类提供的相关方法例如SetChildIndex或者BringToFront和SendToBack等等来修改控件的z-order,从面起到按需调整控件位置的作用。

以下将实现一个利用z-order进行编程的实例。

新建一个窗体Form1,添加一个Panel,再在Panel中从上到下依次画出三个Button控件及对应的三个ListBox控件(大小不必太严格,后面调整了Dock属性后就会对齐)button1,listBox1, button2,listBox2, button3,listBox3。设想程序运行的最早的初始情况是button1, button2, button3均停靠在Panel的上边缘,然后接着是listBox3。因些将三个Button控件的Dock属性设为Top,而将listBox1和ListBox2的Visible属性设置为false,ListBox2设置为true.

到此界面设计完毕,接着主要的代码编写步骤如下:

a.在Form类中添加如下变量用于存放panel中的所有子控件的初始位置信息。

private const int numOfcontrols=6;//子控件数量

private Control []controlsOriginalPosition;

b.在Form类的构造函数中初始化该控件数组变量

controlsOriginalPosition=new Control[numOfcontrols];

//数组中依次存放的是panel中从下到上的子控件

controlsOriginalPosition[0]=this.listBox3;

controlsOriginalPosition[1]=this.button3;

controlsOriginalPosition[2]=this.listBox2;

controlsOriginalPosition[3]=this.button2;

controlsOriginalPosition[4]=this.listBox1;

controlsOriginalPosition[5]=this.button1;

c.在Form类中添加如下函数

//对于一个容器控件中的控件集合,将集合中的所有控件的索引进行修改,

//以改变控件停靠在容器同一边时的排列位置。

//例如所有控件的索引从屏幕的下面到上面依次为:0 1 2 3.

//对应的controlsOriginalPosition中的控件索引依次为:0 1 2 3

//若conToChangePosi的索引为2,则将controlsOriginalPosition中的控件索引依次修改为:1 0 2 3

//其中索引为2 3的将放到容器上面,索引为1 0的将放到容器下面

private bool changeConPosi(Control parentOfCon,Control conToChangePosi)

{

int index=0;

//

//在存放了控件集合的数组中找到该控件

//

for(index=0;index<numOfcontrols;index++)

{

if(conToChangePosi==controlsOriginalPosition[index])

break;

}

if(index==numOfcontrols)

return false;

//

//依次修改控件索引值

//

if(index>0)

for(int i=0;i<index;i++) //修改排在index前面的索引部分 parentOfCon.Controls.SetChildIndex(controlsOriginalPosition[i],index-1-i);

for(int i=index;i<numOfcontrols;i++) //修改排在index后面的索引部分

parentOfCon.Controls.SetChildIndex(controlsOriginalPosition[i],i);

//

//修改索引值完毕后,重新排列控件顺序

//

for(int i=0;i<index;i++)

controlsOriginalPosition[i].Dock=DockStyle.Bottom;

for(int i=index;i<numOfcontrols;i++)

controlsOriginalPosition[i].Dock=DockStyle.Top;

return true;

}

d.建立各button的单击事件处理函数,仅举button1的例子如下:

private void button1_Click(object sender, System.EventArgs e)

{

changeConPosi(this.panel1,this.button1);

this.listBox1.Visible=true;

this.listBox2.Visible=false;

this.listBox3.Visible=false;

this.listBox1.Dock=DockStyle.Fill;

}

最终程序运行效果如下:

单击button1

单击button2

单击button3

当然,将窗体中的Panel换成GroupBox,或者将ListBox换成ListView,TreeView等其它控件也是可以的,或者控件总数目有所变化挺方便的,不需要修改changeConPosi函数,而只需要修改controlsOriginalPosition数组的初始化部分。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: