您的位置:首页 > 其它

WinForm界面开发论(二)容器控件论

2007-08-24 14:04 351 查看
我们的生活中存在着大量的容器关系,比如吃饭需要有碗装米饭,碗放在桌上,桌在家里,家在某一栋楼内,楼在小区内...。一层一层的,控件开发也是这样。在上一篇中,我们介绍了一个简单的控件是如何编写的,本章再说说怎样实现多级的控件。

说到这里,我们需要一个例子,ACDSEE有个展现目录下所有文件夹和图片的控件,如下图。我们将一步步对该控件的开发过程进行详解。



第一步,我们新建一个用户控件,假设名称为ImageBox,为类加上声明语句:


[Designer("System.Windows.Forms.Design.ParentControlDesigner,System.Design")]


public partial class ImageBox : UserControl




...{


//.....

这样,ImageBox就为定义为容器控件,它可以摆放其他控件在容器控件里面。
第二部,我们再新建一个用户控件,就是每个显示图片的子项了,名称为ImageItem,并在设计器中设计它!

第三步,容器里面的项,和ListView的ListViewItem一样,里面有一个ItemList的集合,我们也需要实现这样的结合,并且希望可以使用[int]来获得Box里面的项,要实现集合的结构,我们需要使用System.Collections.ICollection接口,


public class ImageItemCollection : System.Collections.ICollection




...{


private SortedList items = new SortedList();




public int Count




...{


get




...{


return items.Count;


}


}




//------------------------------------事件----------------------------------------


public delegate void itemDelegate(ImageItem itemIsAdd,int addIndex);


public event itemDelegate AddItem;




//------------------------------------属性----------------------------------------


public ImageItem this[int index]




...{


get




...{


object tmp = items.GetByIndex(index);


return (ImageItem)tmp;


}


}




public ImageItem this[string name]




...{


get




...{


object tmp = items[name];


return (ImageItem)tmp;


}


}




//------------------------------------方法----------------------------------------




public void RemoveAll()




...{


this.RemoveAllItem();


items.Clear();


}






/**//// <summary>


/// 添加一个新的图片项


/// </summary>


/// <param name="itemIsAdd">要添加的图片项</param>


/// <returns>包括新增后的图片项数</returns>


public int Add(ImageItem itemIsAdd)




...{


if (itemIsAdd.Name == "ImageItem")




...{


string autoName = "ImageItemAuto" + getAddItemNum();


itemIsAdd.Name = autoName;


}


if (this.AddItem != null)




...{


this.AddItem(itemIsAdd, items.Count + 1);


}


this.items.Add(itemIsAdd.Name, itemIsAdd);


return items.Count - 1;


}






/**//// <summary>


/// 移除某个图片项


/// </summary>


/// <param name="itemIsRemove">要移除的项</param>


/// <returns>包括新增后的图片项数</returns>


public int Remove(ImageItem itemIsRemove)




...{


if(!items.Contains(itemIsRemove.Name))




...{


throw new Exception("该图片项不在图片容器中");


}


items.Remove(itemIsRemove.Name);


if (this.RemoveItem != null)




...{


this.RemoveItem(itemIsRemove);


}


return items.Count - 1;


}




private int addItemNum = 0;


private string getAddItemNum()




...{


addItemNum = addItemNum + 1;


return addItemNum.ToString();


}




#endregion


}


}

第四步,我们需要把集合,容器,子项目这三个东西组装在一起,就完成了我们的图片展现控件了。我们在ImageBox类中加入下面的代码:


public ImageItemCollection Items = new ImageItemCollection();




private void ImageView_Load(object sender, EventArgs e)




...{


Items.AddItem += new ImageItemCollection.itemDelegate(Items_AddItem);


}




private void Items_AddItem(ImageItem itemIsAdd, int itemIndex)




...{


itemIsAdd.Size = itemSize;


this.Controls.Add(itemIsAdd);


this.setImageLocation(itemIsAdd, itemIndex);


}




private void setImageLocation(ImageItem itemIsAdd, int itemIndex)




...{


int columnNum = this.calculationsColumn();


int imageItemX = 0;


if (itemIndex % columnNum != 0)




...{


imageItemX = ((itemIndex % columnNum) - 1) * (itemSize.Width + ImageLayout) + ImageLayout;


}


else




...{


imageItemX = (columnNum - 1) * (itemSize.Width + ImageLayout) + ImageLayout;


}




int rowNum = (itemIndex - 1) / columnNum;


int imageItemY = rowNum * (itemSize.Height + ImageLayout) + ImageLayout;




//itemIsAdd.Location = new Point(imageItemX, imageItemY);


itemIsAdd.Left = imageItemX;


itemIsAdd.Top = imageItemY + this.lbl_Point.Top;


}




private int calculationsColumn()




...{


int thisWidth = this.Size.Width;


int itemWidth = itemSize.Width + ImageLayout;


int columnNum = thisWidth / itemWidth;


return columnNum;


}





但调用项集合类的Add的时候,会在Box发生Add时间,把新项添加到Box中,并且根据需要,设置图片被插入的位置。如果还有其他的需要,如remove,设置item的大小,定义子项的双击事件等等,读者可以根据本章和上一章的原理,对控件进行扩展。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: