大年初八,自己又过一年,新的一年,祝园子里面的所有人新年新气象,猪年行大运,给大家拜年了!
入园先给大家送上小小的一份礼物,“动态邦定ListView组件”。
      此组件的功能就是实现实体层与界面显示(ListView)进行动态绑定,这方面的知识园子里面的高手应该都实现过。
首先大家先看看类图

具体的实现代码如下:

using System;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Entity
{    

    
#region 定义相关委托
    
public delegate void ItemIndexEventHandler(object sender,ItemIndexEventArgs e);
    
public delegate void ItemEventHandler(object sender,ItemEventArgs e);

    
//包含事件数据的派生类
    public class ItemIndexEventArgs : EventArgs
    
{
        
public ItemIndexEventArgs(int index)
        
{
            
this.index = index;
        }

        
private int index;
        
public int Index
        
{
            
get
            
{
                
return index;
            }

        }

    }


    
public class ItemEventArgs : EventArgs
    
{
        
public ItemEventArgs(IListElementWithEvent obj)
        
{
            
this.obj = obj;
        }

        
private IListElementWithEvent obj;
        
public IListElementWithEvent Obj
        
{
            
get
            
{
                
return obj;
            }

        }

    }

    
#endregion


    
#region 对象修改通知接口
    
/// <summary>
    
/// 对象修改通知接口
    
/// 实现此接口的类应该在类的每个属性值改变时发送ItemEventHandler通知
    
/// </summary>

    public interface IListElementWithEvent
    
{
        
string[] GetValueStrings();

        
event EventHandler ItemChanged;
    }


    
/// <summary>
    
/// 对象链表修改通知接口
    
/// 实现此接口的类应该在此链表的各个对象进行增加移出等操作时发送ItemIndexEventHandler或ItemEventHandler通知
    
/// </summary>

    public interface IListWithEvent : IEnumerable
    
{
        
event ItemIndexEventHandler ItemAtRemoved;
        
event ItemEventHandler ItemAdded;
        
event ItemEventHandler ItemRefRemoved;
    }

    
#endregion


    
#region    包装IListElementWithEvent的DataListViewItem类
    
/// <summary>
    
/// 把IListElementWithEvent包装为DataListViewItem类,
    
/// 并把IListElementWithEvent与DataListViewItem进行绑定,
    
/// 当实体数据修改时,对应的显示对象也进行修改
    
/// </summary>

    abstract public class DataListViewItem : ListViewItem
    
{
        
public DataListViewItem(IListElementWithEvent source,bool isShowNo)
            : 
base(source.GetValueStrings())
        
{
            
this.isShowNo = isShowNo;
            
//this.Tag = source;
            
//实现实体对象与显示对象的绑定
            source.ItemChanged +=new EventHandler(source_ItemChanged);
        }


        
public DataListViewItem(IListElementWithEvent source): this(source,false)
        
{}
        
private bool isShowNo = false;


        
/// <summary>
        
/// 修改显示对象的SubItems值
        
/// </summary>
        
/// <param name="sender">实现IListElementWithEvent接口的类的对象</param>

        private void source_ItemChanged(object sender,EventArgs e)
        
{
            
string[] x = ((IListElementWithEvent)sender).GetValueStrings();
            
if(x.Length != SubItems.Count)
                
throw new ArgumentException("传入显示列数错误");
            
for(int i=0; i< x.Length; i++)
            
{
                
if(isShowNo && i == 0)continue;
                SubItems[i].Text 
= x[i];
            }

        }

    }

    
#endregion


    
#region    实现显示的DataListView类
    
/// <summary>
    
/// 实现显示的DataListView类
    
/// </summary>

    abstract public class DataListView : ListView
    
{
        
/// <summary>
        
/// 
        
/// </summary>
        
/// <param name="srclist">对象链表</param>
        
/// <param name="showNo">是否显示顺序编号</param>

        public DataListView(IListWithEvent srclist, bool showNo)
        
{
            
//把EntityList直接包装到DataListView里面
            
//并进行增加,删除操作的绑定
            this.showNo = showNo;
            
this.SetBindingList(srclist);
            
this.Activation = ItemActivation.OneClick;
        }


        
public DataListView(IListWithEvent srclist)
            : 
this(srclist, false)
        
{
        }


        
private IListWithEvent bindingList;

        
bool showNo = false;

        
//是否现实顺序编号
        public bool ShowHeaderNo
        
{
            
get
            
{
                
return showNo;
            }

        }



        
//绑定对象链表
        public virtual void SetBindingList(IListWithEvent list)
        
{
            
if (this.bindingList == list)
                
return;

            
//解除前次绑定
            if (this.bindingList != null)
            
{
                
this.Items.Clear();
                bindingList.ItemAdded 
-= new ItemEventHandler(DoAdd);
                bindingList.ItemAtRemoved 
-= new ItemIndexEventHandler(DoRemoveAt);
                bindingList.ItemRefRemoved 
-= new ItemEventHandler(DoRemove);
            }


            
this.bindingList = list;
            
//进行当前绑定
            if (this.bindingList != null)
            
{
                
foreach (IListElementWithEvent temp in list)
                
{
                    
this.Items.Add(CreatItem(temp));
                }

                list.ItemAdded 
+= new ItemEventHandler(DoAdd);
                list.ItemAtRemoved 
+= new ItemIndexEventHandler(DoRemoveAt);
                list.ItemRefRemoved 
+= new ItemEventHandler(DoRemove);
            }

            CreateID();

        }



        
/// <summary>
        
/// 创建顺序编号
        
/// </summary>

        public void CreateID()
        
{
            
if (this.showNo)
            
{
                
for (int i = 0; i < this.Items.Count; i++)
                
{
                    
this.Items[i].Text = (i + 1).ToString();
                }

            }

        }


        
//进行增加操作
        protected void DoAdd(object sender, ItemEventArgs e)
        
{
            
this.Items.Add(CreatItem(e.Obj));
            CreateID();
        }


        
/// <summary>
        
/// 通过索引进行移出操作
        
/// </summary>
        
/// <param name="index">索引</param>
        
/// <exception cref="ArgumentOutOfRangeException">参数越界异常</exception>

        protected void DoRemoveAt(object sender, ItemIndexEventArgs e)
        
{
            
this.Items.RemoveAt(e.Index);
            CreateID();
        }


        
//通过对象进行移出操作
        protected void DoRemove(object sender, ItemEventArgs e)
        
{
            
this.Items.Remove(FindViewItem(e.Obj));
            CreateID();
        }

        
/// <summary>
        
/// 把实现IListElementWithEvent接口的类的对象包装为DataListViewItem,并进行数据对象与显示对象的绑定
        
/// </summary>
        
/// <param name="src">实现IListElementWithEvent接口的类的对象</param>
        
/// <returns>经过包装过的DataListViewItem</returns>

        protected abstract DataListViewItem CreatItem(IListElementWithEvent src);

        
/// <summary>
        
/// 通过用实现IListElementWithEvent接口的类的对象找到对应绑定的显示对象
        
/// </summary>
        
/// <param name="src">实现IListElementWithEvent接口的类的对象</param>
        
/// <returns>经过包装过的DataListViewItem<</returns>

        protected abstract DataListViewItem FindViewItem(IListElementWithEvent src);
    }

    
#endregion


}


只要在实体层实现IListElementWithEvent与IListWithEvent接口,然后在显示层分别根据需要定义继承DataListView与DataListViewItem的显示类就可以实现动态绑定了。
显示层代码demo如下:

public class CancelInstructionListView : DataListView
        


        
public class CancelInstructionListViewItem : DataListViewItem
        

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3