jjccx

jjccx's blog
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

对ListView的加强

Posted on 2005-03-28 18:14  jjccx  阅读(2207)  评论(5)    收藏  举报
    注:这里针对ListView的Detail View
    在所有的列表控件中,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

 

(待续)