构建基于ListView(Win)的数据绑定对象
在利用ListView进行数据显示时,经常做些设置Columns、生成相关ListViewItem和添加到ListView等工作;以上工作都很烦琐,更重要的是没有一个统一规则的情况下编写很容易搞得UI代码非常零乱导致代码不好维护和修改。为了解决以上问题所以编写一个基于ListView的数据绑定处理规则,除了简化代码编写外更重要的是提高代码的重用性。下面描述数据绑定对象的实现和具体使用。
建立相关的数据绑定规则:
/// <summary>
/// 基于ListView控件的数据显示描述接口
/// </summary>
/// <typeparam name="T">相关数据实体类型</typeparam>
public interface IViewData<T>
{
/// <summary>
/// 数据绑定过程
/// </summary>
/// <param name="items">数据实体对象集</param>
void DataBind(IList<T> items);
/// <summary>
/// 根据实体对象构造相关显示项
/// </summary>
/// <param name="item">数据实体对象</param>
/// <returns>ListViewItem</returns>
System.Windows.Forms.ListViewItem CreateItem(T item);
/// <summary>
/// 创建相关列信息
/// </summary>
void CreateColumns();
/// <summary>
/// 获取当前选择的数据项
/// </summary>
T SelectItem
{
get;
}
/// <summary>
/// 数据绑定事件,每一项数据绑定会引发这个事件
/// </summary>
event EventViewDataBound<T> ViewDataBound;
/// <summary>
/// 获取相关的ListView控件
/// </summary>
System.Windows.Forms.ListView ListView
{
get;
}
}
/// <summary>
/// 数据绑定委托描述
/// </summary>
/// <typeparam name="T">类型实体类型</typeparam>
/// <param name="item">实体对象</param>
/// <param name="viewitem">列表项对象</param>
public delegate void EventViewDataBound<T>(T item,System.Windows.Forms.ListViewItem viewitem);
为了简化其扩展实现制定基础适配器对象
/// <summary>
/// 数据显示适配器对象
/// 抽象基本通过功能,简化派生类的实现
/// </summary>
/// <typeparam name="T">相关数据实体类型</typeparam>
public abstract class ViewDataAdapter<T>:IViewData<T>
{
public ViewDataAdapter(System.Windows.Forms.ListView view)
{
mListView = view;
CreateColumns();
ListView.FullRowSelect = true;
}
#region IViewData<T> 成员
public void DataBind(IList<T> items)
{
System.Windows.Forms.ListViewItem vi;
foreach (T item in items)
{
vi = CreateItem(item);
if (ViewDataBound != null)
ViewDataBound(item, vi);
ListView.Items.Add(vi);
}
}
public System.Windows.Forms.ListViewItem CreateItem(T item)
{
System.Windows.Forms.ListViewItem vitem= OnCreateItem(item);
vitem.Tag = item;
return vitem;
}
protected abstract System.Windows.Forms.ListViewItem OnCreateItem(T item);
public void CreateColumns()
{
if (ListView.Columns.Count > 0)
return;
OnCreateColumns();
}
protected abstract void OnCreateColumns();
public T SelectItem
{
get
{
if (ListView.SelectedItems.Count == 0)
return default(T);
return (T)ListView.SelectedItems[0].Tag;
}
}
public event EventViewDataBound<T> ViewDataBound;
private System.Windows.Forms.ListView mListView;
public System.Windows.Forms.ListView ListView
{
get { return mListView; }
}
#endregion
}
以上代码描述数据绑定器的实现,接下来看下如何继承于ViewDataAdapter实现具体的数据绑定对象:
public class BootView:ViewDataAdapter<BootInfo>
{
public BootView(System.Windows.Forms.ListView view) : base(view) { }
protected override void OnCreateColumns()
{
System.Windows.Forms.ColumnHeader col;
col = new System.Windows.Forms.ColumnHeader();
col.Text = "服务目录";
col.Width = 200;
ListView.Columns.Add(col);
col = new System.Windows.Forms.ColumnHeader();
col.Text = "描述";
col.Width = 500;
ListView.Columns.Add(col);
}
protected override System.Windows.Forms.ListViewItem OnCreateItem(BootInfo item)
{
return new System.Windows.Forms.ListViewItem(
new string[] {item.BootDirectory,item.Remark });
}
}
派生数据绑定对象只需要重写两个方法:一个方法是创建相关列信息,另一个方法是描述创建具体的ListViewItem。由于数据绑定对象的独立性因此可以和任何UI下的ListView进行绑定输出,这样可以大大提高代码的重用性。
下面让我们看一下BootView是如何和UI的ListView进行整合显示数据的:
//定义数据绑定对象
mViewData = new NetFiles.Common.DataViews.BootView(listDirectory);
IBoot boot = AccessFactory.CreateBoot();
mViewData.ViewDataBound += delegate(BootInfo item,ListViewItem vitem) {
//定义数据绑定处理匿名函数
};
//数据绑定输出
mViewData.DataBind(boot.List());
这个数据绑定器实现并不复杂,但可以统一UI代码编写的规则,并把处理规则以模块的方式单独抽取出来从而达到良好的代码重用性。由于这个数据绑定器是根据自己实际情况需要制定出来的,因此对于某些情况处理可能存在问题;对于发现代码有问题或不足的朋友请多提意见。