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

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

    说到这里,我们需要一个例子,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的大小,定义子项的双击事件等等,读者可以根据本章和上一章的原理,对控件进行扩展。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值