在所有的列表控件中,ListView应该算是外观最漂亮的了,当然,如果哪位觉得其他的,比如说DataGrid,可以实现让外观更漂亮,请通知我一下,让我也学习学习,进步进步。但是ListView的缺点是不能实现数据绑定等等,我们现在的目的就是要实现相关的功能。
1.参考了WebForm中DataGrid的源代码,我们为ListView添加数据绑定功能(还不能绑定ContainsListCollection==true的数据源,哪位高手知道请告诉我,谢谢),源代码如下(代码可能不完整,有些东西定义在其他文件里,我将会提供完整工程下载):
#region 私有成员
private ColumnHeader _autoGroupCol = null;
private ArrayList _autoGroupList = new ArrayList();
private ListViewItemCollection _items;
private ListViewGroupCollection _groups;
private bool _showInGroups = false;
private bool _autoGroup = false;
private string _emptyAutoGroupText = "";
private IntPtr _apiRetVal;
private object dataSource = null;
private CurrencyManager currencyManager = null;
private int[] columnWidth = null;
#endregion 私有成员
#region 绑定
/// <summary>
/// 获取或设置 J.Control.ListView 所显示数据的数据源。
/// </summary>
public object DataSource
{
get
{
return this.dataSource;
}
set
{
if(((value != null) && !(value is IList)) && !(value is IListSource))
{
throw new Exception("复杂的 DataBinding 接受 IList 或 IListSource 作为数据源。");
}
if((this.dataSource != null) && this.dataSource.Equals(value))
{
return;
}
if(value is IListSource)
{
IListSource listSource = (IListSource)value;
if(listSource.ContainsListCollection == true)
throw new Exception("暂时不支持此数据源……");
}
if(value == null)
return;
this.dataSource = value;
currencyManager = (CurrencyManager)this.BindingContext[value];
}
}
/// <summary>
/// 将控件及其所有子控件绑定到 J.Control.ListViewEx.DataSource 属性指定的数据源。
/// </summary>
public void DataBind()
{
PropertyDescriptor propertyDescriptor;
PropertyDescriptorCollection propertyDescriptors = currencyManager.GetItemProperties();
int _columnWidth = 0;
int columnCount = propertyDescriptors.Count;
const int verticalCellLeeway = 14;
columnWidth = new int[columnCount];
IList innerList = currencyManager.List;
int rowCount = innerList.Count;
bool firstItem = true;
this.Clear();
#region 添加行
object obj = null;
string cellText = null;
for(int i = 0; i < rowCount; i++)
{
firstItem = true;
obj = innerList[i];
ListViewItem listViewItem = new ListViewItem();
propertyDescriptor = propertyDescriptors[0];
if(propertyDescriptor.IsBrowsable)
{
cellText = propertyDescriptor.GetValue(obj).ToString();
_columnWidth = GetStringWidth(cellText);
if(_columnWidth > columnWidth[0])
columnWidth[0] = _columnWidth;
listViewItem.Text= cellText;
firstItem = false;
}
for(int j = 1; j < columnCount; j++)
{
propertyDescriptor = propertyDescriptors[j];
if(propertyDescriptor.IsBrowsable)
{
cellText = propertyDescriptor.GetValue(obj).ToString();
_columnWidth = GetStringWidth(cellText);
if(_columnWidth > columnWidth[j])
columnWidth[j] = _columnWidth;
if(firstItem)
{
listViewItem.Text = cellText;
firstItem = false;
}
else
{
listViewItem.SubItems.Add(cellText);
}
}
}
this.Items.Add(listViewItem);
}
#endregion 添加行
#region 添加表头
string columnText = null;
for(int i = 0; i < columnCount; i++)
{
propertyDescriptor = propertyDescriptors[i];
if(propertyDescriptor.IsBrowsable)
{
columnText = propertyDescriptor.Name;
ColumnHeader ch = new ColumnHeader();
ch.Text = columnText;
_columnWidth = GetStringWidth(columnText);
if(_columnWidth > columnWidth[i])
columnWidth[i] = _columnWidth;
ch.Width = columnWidth[i] + verticalCellLeeway;
this.Columns.Add(ch);
}
}
#endregion 添加表头
}
#endregion 绑定
#region Column
/// <summary>
/// 以列的标头文本来查找列的索引。
/// </summary>
/// <param name="name">列的标头文本。</param>
/// <returns>列的索引。</returns>
public int GetColumnIndexByText(string text)
{
for(int i = 0; i < this.Columns.Count; i++)
{
if(this.Columns[i].Text.ToLower() == text.ToLower())
{
return i;
}
}
return -1;
}
#endregion Column
#region StringHelper
/// <summary>
/// 得到字符串的宽度。
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
protected int GetStringWidth(string s)
{
Graphics g = Graphics.FromImage(new Bitmap(32, 32));
SizeF strSize = g.MeasureString(s, this.Font);
return ((int)strSize.Width);
}
#endregion Helper
浙公网安备 33010602011771号