using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Data;
using System.Linq;
//namespace ListViewEmbeddedControls
namespace VideoMagic
{
public class ListViewEx : ListView
{
#region Interop-Defines
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wPar, IntPtr lPar);
// ListView messages
private const int LVM_FIRST = 0x1000;
private const int LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + 59);
// Windows Messages
private const int WM_PAINT = 0x000F;
#endregion
/// <summary>
/// Structure to hold an embedded control's info
/// </summary>
private struct EmbeddedControl
{
public Control Control;
public int Column;
public int Row;
public DockStyle Dock;
public ListViewItem Item;
}
/
//数据相关
public DataTable listTable = new DataTable();//对应的table
public DataTable listPageTable = new DataTable();//对应的table
//private bool blnModFlag = false;//是否可以修改标志
public EventHandler ModHandler;//修改句柄
public EventHandler DelHandler;//删除句柄
public enum LISTTYPE : uint
{
LV_TASK = 0,
LV_USER,
LV_LOG
}
public LISTTYPE blnlvFlag = LISTTYPE.LV_LOG;//列表类型标志
public ToolStripTextBox pagebox;
/
private ArrayList _embeddedControls = new ArrayList();
public ListViewEx() {
}
protected override void OnColumnClick(ColumnClickEventArgs e)
{
if (Columns[e.Column].Tag == null)
Columns[e.Column].Tag = true;
bool tabK = (bool)Columns[e.Column].Tag;
if (tabK)
Columns[e.Column].Tag = false;
else
Columns[e.Column].Tag = true;
ListViewItemSorter = new ListViewSort(e.Column, Columns[e.Column].Tag); //指定排序器并传送列索引与升序降序关键字
Sort();//对列表进行自定义排序
ListViewItemSorter = null;
}
/// <summary>
/// Retrieve the order in which columns appear
/// </summary>
/// <returns>Current display order of column indices</returns>
protected int[] GetColumnOrder()
{
IntPtr lPar = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * Columns.Count);
IntPtr res = SendMessage(Handle, LVM_GETCOLUMNORDERARRAY, new IntPtr(Columns.Count), lPar);
if (res.ToInt32() == 0) // Something went wrong
{
Marshal.FreeHGlobal(lPar);
return null;
}
int [] order = new int[Columns.Count];
Marshal.Copy(lPar, order, 0, Columns.Count);
Marshal.FreeHGlobal(lPar);
return order;
}
/// <summary>
/// Retrieve the bounds of a ListViewSubItem
/// </summary>
/// <param name="Item">The Item containing the SubItem</param>
/// <param name="SubItem">Index of the SubItem</param>
/// <returns>Subitem's bounds</returns>
protected Rectangle GetSubItemBounds(ListViewItem Item, int SubItem)
{
Rectangle subItemRect = Rectangle.Empty;
if (Item == null)
throw new ArgumentNullException("Item");
int[] order = GetColumnOrder();
if (order == null) // No Columns
return subItemRect;
if (SubItem >= order.Length)
throw new IndexOutOfRangeException("SubItem "+SubItem+" out of range");
// Retrieve the bounds of the entire ListViewItem (all subitems)
Rectangle lviBounds = Item.GetBounds(ItemBoundsPortion.Entire);
int subItemX = lviBounds.Left;
// Calculate the X position of the SubItem.
// Because the columns can be reordered we have to use Columns[order[i]] instead of Columns[i] !
ColumnHeader col;
int i;
for (i=0; i<order.Length; i++)
{
col = this.Columns[order[i]];
if (col.Index == SubItem)
break;
subItemX += col.Width;
}
subItemRect = new Rectangle(subItemX, lviBounds.Top, this.Columns[order[i]].Width, lviBounds.Height);
return subItemRect;
}
/// <summary>
/// Add a control to the ListView
/// </summary>
/// <param name="c">Control to be added</param>
/// <param name="col">Index of column</param>
/// <param name="row">Index of row</param>
public void AddEmbeddedControl(Control c, int col, int row)
{
AddEmbeddedControl(c,col,row,DockStyle.Fill);
}
/// <summary>
/// Add a control to the ListView
/// </summary>
/// <param name="c">Control to be added</param>
/// <param name="col">Index of column</param>
/// <param name="row">Index of row</param>
/// <param name="dock">Location and resize behavior of embedded control</param>
public void AddEmbeddedControl(Control c, int col, int row, DockStyle dock)
{
if (c==null)
throw new ArgumentNullException();
if (col>=Columns.Count || row>=Items.Count)
throw new ArgumentOutOfRangeException();
EmbeddedControl ec;
ec.Control = c;
ec.Column = col;
ec.Row = row;
ec.Dock = dock;
ec.Item = Items[row];
_embeddedControls.Add(ec);
// Add a Click event handler to select the ListView row when an embedded control is clicked
c.Click += new EventHandler(_embeddedControl_Click);
this.Controls.Add(c);
}
/// <summary>
/// Remove a control from the ListView
/// </summary>
/// <param name="c">Control to be removed</param>
public void RemoveEmbeddedControl(Control c)
{
if (c == null)
throw new ArgumentNullException();
for (int i=0; i<_embeddedControls.Count; i++)
{
EmbeddedControl ec = (EmbeddedControl)_embeddedControls[i];
if (ec.Control == c)
{
c.Click -= new EventHandler(_embeddedControl_Click);
this.Controls.Remove(c);
_embeddedControls.RemoveAt(i);
return;
}
}
throw new Exception("Control not found!");
}
/// <summary>
/// Retrieve the control embedded at a given location
/// </summary>
/// <param name="col">Index of Column</param>
/// <param name="row">Index of Row</param>
/// <returns>Control found at given location or null if none assigned.</returns>
public Control GetEmbeddedControl(int col, int row)
{
foreach (EmbeddedControl ec in _embeddedControls)
if (ec.Row == row && ec.Column == col)
return ec.Control;
return null;
}
[DefaultValue(View.LargeIcon)]
public new View View
{
get
{
return base.View;
}
set
{
// Embedded controls are rendered only when we're in Details mode
foreach (EmbeddedControl ec in _embeddedControls)
ec.Control.Visible = (value == View.Details);
base.View = value;
}
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_PAINT:
if (View != View.Details)
break;
// Calculate the position of all embedded controls
foreach (EmbeddedControl ec in _embeddedControls)
{
Rectangle rc = this.GetSubItemBounds(ec.Item, ec.Column);
if ((this.HeaderStyle != ColumnHeaderStyle.None) &&
(rc.Top<this.Font.Height)) // Control overlaps ColumnHeader
{
ec.Control.Visible = false;
continue;
}
else
{
ec.Control.Visible = true;
}
switch (ec.Dock)
{
case DockStyle.Fill:
break;
case DockStyle.Top:
rc.Height = ec.Control.Height;
break;
case DockStyle.Left:
rc.Width = ec.Control.Width;
break;
case DockStyle.Bottom:
rc.Offset(0, rc.Height-ec.Control.Height);
rc.Height = ec.Control.Height;
break;
case DockStyle.Right:
rc.Offset(rc.Width-ec.Control.Width, 0);
rc.Width = ec.Control.Width;
break;
case DockStyle.None:
rc.Size = ec.Control.Size;
break;
}
// Set embedded control's bounds
ec.Control.Bounds = rc;
}
break;
}
base.WndProc (ref m);
}
private void _embeddedControl_Click(object sender, EventArgs e)
{
// When a control is clicked the ListViewItem holding it is selected
foreach (EmbeddedControl ec in _embeddedControls)
{
if (ec.Control == (Control)sender)
{
this.SelectedItems.Clear();
ec.Item.Selected = true;
}
}
}
/
//分页相关
public int pageSize = 50;//每页显示的行数
private int pageTotalCountRecord = 0;//总记录数
public int pageCount = 0;//总页数
private int pageCurrent = 0;//当前页数
private int PagecurrentRow = 0;//当前记录行
private int PageOldRow = 0;//记录上一次当前记录数
public int PageJumpRow = 1;//跳转到指定页
/// <summary>
/// 初始化页
/// </summary>
public void InitPage()
{
//pageSize = 5;//每页显示行数
pageTotalCountRecord = listTable.Rows.Count;//总行数
pageCount = pageTotalCountRecord / pageSize;
if (pageTotalCountRecord % pageSize > 0) pageCount++;
pageCurrent = 1;
PagecurrentRow = 0;//当前记录数从零开始
PageOldRow = PagecurrentRow;//记录上一次当前记录数
UpdateList();
}
/// <summary>
/// 首页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void btnFirstPage_Click(object sender, EventArgs e)
{
pageCurrent = 1;
PagecurrentRow = 0;
UpdateList();
}
/// <summary>
/// 下一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void btnPageDown_Click(object sender, EventArgs e)
{
pageCurrent++;
if (pageCurrent > pageCount)
{
pageCurrent = pageCount;
return;
}
PagecurrentRow = (pageCurrent - 1) * pageSize;
UpdateList();
}
/// <summary>
/// 跳转到指定页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void btnPageJump_Click(object sender, EventArgs e)
{
//int page = PageJumpRow;
int page = int.Parse(pagebox.Text);
if (page == pageCurrent || pageTotalCountRecord == 0)
{
return;
}
if (page < 1)
{
page = 1;
}
if (page > pageCount)
{
page = pageCount;
}
pageCurrent = page;
PagecurrentRow = (pageCurrent - 1) * pageSize;
UpdateList();
} /// <summary>
/// 上一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void btnPageUp_Click(object sender, EventArgs e)
{
pageCurrent--;
if (pageCurrent < 1)
{
pageCurrent = 1;
return;
}
PagecurrentRow = (pageCurrent - 1) * pageSize;
UpdateList();
}
/// <summary>
/// 尾页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void btnLastPage_Click(object sender, EventArgs e)
{
pageCurrent = pageCount;
PagecurrentRow = (pageCurrent - 1) * pageSize;
UpdateList();
}
private void UpdateList()
{
this.Items.Clear();
int nStartRow = 0;
int nEndRow = 0;
if (pageCurrent >= pageCount)
{
nEndRow = pageTotalCountRecord;//最后一条记录
}
else
{
nEndRow = pageSize * pageCurrent;
}
nStartRow = PagecurrentRow;
listPageTable.Clear();
PageOldRow = PagecurrentRow;
for (int i = nStartRow; i < nEndRow; i++)
{
listPageTable.ImportRow(listTable.Rows[i]);
PagecurrentRow++;
}
ShowDataInListView();
if (pagebox != null) pagebox.Text = pageCurrent.ToString();
}
public void UpdateListInfo()
{
PagecurrentRow = PageOldRow;
UpdateList();
}
public void UpdateListInfobyId(string id)
{
DataRow[] datarows = listPageTable.Select("TaskId='" + int.Parse(id) + "'");
if (datarows.Count() > 0)
{
PagecurrentRow = PageOldRow;
UpdateList();
}
}
public void SetPage(int page)
{
PageJumpRow = page;
}