创建可编辑ListView控件
ListView控件是一个在Windows应用程序中使用频率比较高的一个,通常使用它来显示数据报表。很多情况下,我们不仅仅使用ListView来显示数据,还要求编辑其中的数据。但是.NET提供的ListView控件的编辑功能十分有限,只能编辑首列,编辑格式只能为文本框,等等,使用起来甚为不便。因此本人新写了一个类,扩充了其功能,客户程序员可以设置任何列的格式(只读,编辑状态下文本框,编辑状态下组合框), 代码如下:
1.ALAN_ListViewColumnStyle 列风格枚举
/// <summary>
/// 列风格枚举
/// </summary>
public enum ALAN_ListViewColumnStyle
{
ReadOnly, //只读
EditBox, //编辑状态下显示为文本框
ComboBox //编辑状态下显示为组合框
};
2.ALAN_ColumnHeader 带有自定义风格的列
/// <summary>
/// 列描述
/// </summary>
public class ALAN_ColumnHeader : ColumnHeader
{
private ALAN_ListViewColumnStyle cs; //本列的风格
public ALAN_ColumnHeader() : base()
{
cs = ALAN_ListViewColumnStyle.ReadOnly;
}
public ALAN_ColumnHeader(ALAN_ListViewColumnStyle _cs)
{
cs = _cs;
}
public ALAN_ListViewColumnStyle ColumnStyle
{
get { return cs; }
set { cs = value;}
}
}
3.ALAN_EditListView 列表控件
using System.Drawing;
/// <summary>
/// 可编辑的ListView控件
/// </summary>
public class ALAN_EditListView : ListView
{
private ListViewItem m_currentLVItem;
private int m_nX = 0;
private int m_nY = 0;
private string m_strSubItemText;
private int m_nSubItemSelected = 0;
private ComboBox[] m_arrComboBoxes = new ComboBox[20];
private System.Windows.Forms.TextBox editBox;
private Font m_fontComboBox;
private Font m_fontEdit;
private Color m_bgcolorComboBox;
private Color m_bgcolorEdit;
public ALAN_EditListView()
{
editBox = new System.Windows.Forms.TextBox();
this.ComboBoxFont = this.Font;
this.EditFont = this.Font;
this.EditBgColor = Color.LightBlue;
this.m_bgcolorComboBox = Color.LightBlue;
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.SMKMouseDown);
this.DoubleClick += new System.EventHandler(this.SMKDoubleClick);
this.GridLines = true;
editBox.Size = new System.Drawing.Size(0, 0);
editBox.Location = new System.Drawing.Point(0, 0);
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.editBox });
editBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.EditOver);
editBox.LostFocus += new System.EventHandler(this.FocusOver);
editBox.AutoSize = true;
editBox.Font = this.EditFont;
editBox.BackColor = this.EditBgColor;
editBox.BorderStyle = BorderStyle.FixedSingle;
editBox.Hide();
editBox.Text = "";
}
public Font ComboBoxFont
{
get { return this.m_fontComboBox; }
set { this.m_fontComboBox = value; }
}
public Color ComboBoxBgColor
{
get { return this.m_bgcolorComboBox; }
set
{
this.m_bgcolorComboBox = value;
for (int i = 0; i < this.m_arrComboBoxes.Length; i++)
{
if (m_arrComboBoxes[i] != null)
m_arrComboBoxes[i].BackColor = this.m_bgcolorComboBox;
}
}
}
public Font EditFont
{
get { return this.m_fontEdit; }
set
{
this.m_fontEdit = value;
this.editBox.Font = this.m_fontEdit;
}
}
public Color EditBgColor
{
get { return this.m_bgcolorEdit; }
set
{
this.m_bgcolorEdit = value;
this.editBox.BackColor = this.m_bgcolorEdit;
}
}
public void SetColumn(int columnIndex, ALAN_ListViewColumnStyle cs)
{
if (columnIndex < 0 || columnIndex > this.Columns.Count)
throw new Exception("Column index is out of range");
((ALAN_ColumnHeader)Columns[columnIndex]).ColumnStyle = cs;
}
public void BoundListToColumn(int columnIndex, string[] items)
{
if (columnIndex < 0 || columnIndex > this.Columns.Count)
throw new Exception("Column index is out of range");
if (((ALAN_ColumnHeader)Columns[columnIndex]).ColumnStyle != ALAN_ListViewColumnStyle.ComboBox)
throw new Exception("Column should be ComboBox style");
ComboBox newbox = new ComboBox();
for (int i = 0; i < items.Length; i++)
newbox.Items.Add(items[i]);
newbox.Size = new System.Drawing.Size(0, 0);
newbox.Location = new System.Drawing.Point(0, 0);
this.Controls.AddRange(new System.Windows.Forms.Control[] { newbox });
newbox.SelectedIndexChanged += new System.EventHandler(this.CmbSelected);
newbox.LostFocus += new System.EventHandler(this.CmbFocusOver);
newbox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.CmbKeyPress);
newbox.Font = this.ComboBoxFont;
newbox.BackColor = this.ComboBoxBgColor;
newbox.DropDownStyle = ComboBoxStyle.DropDownList;
newbox.Hide();
this.m_arrComboBoxes[columnIndex] = newbox;
}
private void CmbKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
ComboBox cmbBox = (ComboBox)sender;
if (e.KeyChar == 13 || e.KeyChar == 27) //CR or ESC press
{
cmbBox.Hide();
}
}
private void CmbSelected(object sender, System.EventArgs e)
{
ComboBox cmbBox = (ComboBox)sender;
int sel = cmbBox.SelectedIndex;
if (sel >= 0)
{
string itemSel = cmbBox.Items[sel].ToString();
m_currentLVItem.SubItems[m_nSubItemSelected].Text = itemSel;
}
}
private void CmbFocusOver(object sender, System.EventArgs e)
{
ComboBox cmbBox = (ComboBox)sender;
cmbBox.Hide();
}
private void EditOver(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
m_currentLVItem.SubItems[m_nSubItemSelected].Text = editBox.Text;
editBox.Hide();
}
if (e.KeyChar == 27)
editBox.Hide();
}
private void FocusOver(object sender, System.EventArgs e)
{
m_currentLVItem.SubItems[m_nSubItemSelected].Text = editBox.Text;
editBox.Hide();
}
public void SMKDoubleClick(object sender, System.EventArgs e)
{
// Check the subitem clicked .
int nStart = m_nX; //current mouse down X position
int spos = 0;
int epos = this.Columns[0].Width;
for (int i = 0; i < this.Columns.Count; i++)
{
if (nStart > spos && nStart < epos)
{
m_nSubItemSelected = i;
break;
}
spos = epos;
epos += this.Columns[i].Width;
}
m_strSubItemText = m_currentLVItem.SubItems[m_nSubItemSelected].Text;
ALAN_ColumnHeader column = (ALAN_ColumnHeader)Columns[m_nSubItemSelected];
if (column.ColumnStyle == ALAN_ListViewColumnStyle.ComboBox)
{
ComboBox cmbBox = this.m_arrComboBoxes[m_nSubItemSelected];
if (cmbBox == null)
throw new Exception("The ComboxBox control bind to current column is null");
Rectangle r = new Rectangle(spos, m_currentLVItem.Bounds.Y, epos, m_currentLVItem.Bounds.Bottom);
cmbBox.Size = new System.Drawing.Size(epos - spos, m_currentLVItem.Bounds.Bottom - m_currentLVItem.Bounds.Top);
cmbBox.Location = new System.Drawing.Point(spos, m_currentLVItem.Bounds.Y);
cmbBox.Show();
cmbBox.Text = m_strSubItemText;
cmbBox.SelectAll();
cmbBox.Focus();
}
if (column.ColumnStyle == ALAN_ListViewColumnStyle.EditBox)
{
Rectangle r = new Rectangle(spos, m_currentLVItem.Bounds.Y, epos, m_currentLVItem.Bounds.Bottom);
editBox.Size = new System.Drawing.Size(epos - spos, m_currentLVItem.Bounds.Height);
editBox.Location = new System.Drawing.Point(spos, m_currentLVItem.Bounds.Y);
editBox.Show();
editBox.Text = m_strSubItemText;
editBox.SelectAll();
editBox.Focus();
}
}
public void SMKMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
m_currentLVItem = this.GetItemAt(e.X, e.Y);
m_nX = e.X;
m_nY = e.Y;
}
}
使用方法如下:
this.listView1 = new ALAN_EditListView();
///////////////////////
///add the columns
ALAN_ColumnHeader header1 = new ALAN_ColumnHeader(ALAN_ListViewColumnStyle.ReadOnly);
header1.Width = 120;
header1.Text = "姓名";
this.listView1.Columns.Add(header1);
ALAN_ColumnHeader header2 = new ALAN_ColumnHeader(ALAN_ListViewColumnStyle.EditBox);
header2.Width = 120;
header2.Text = "性别";
this.listView1.Columns.Add(header2);
ALAN_ColumnHeader header3 = new ALAN_ColumnHeader(ALAN_ListViewColumnStyle.EditBox);
header3.Width = 120;
header3.Text = "年龄";
this.listView1.Columns.Add(header3);
ALAN_ColumnHeader header4 = new ALAN_ColumnHeader(ALAN_ListViewColumnStyle.ComboBox);
header4.Width = 120;
header4.Text = "专业";
this.listView1.Columns.Add(header4);
ALAN_ColumnHeader header5 = new ALAN_ColumnHeader(ALAN_ListViewColumnStyle.ComboBox);
header5.Width = 120;
header5.Text = "轮休";
this.listView1.Columns.Add(header5);
///////////////////////
///bound the combox
this.listView1.BoundListToColumn(3, new string[] { "Lotus", "SQL Server", ".NET", "VB" });
this.listView1.BoundListToColumn(4, new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" });
/////////////////////////////////////
///set edit state font and backcolor
//this.listView1.ComboBoxBgColor = Color.LightYellow;
this.listView1.ComboBoxFont = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.listView1.EditFont = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
///////////////////////
///add rows
string[] s = new string[5];
s[0] = "张三";
s[1] = "男";
s[2] = "24";
s[3] = ".NET";
s[4] = "Sun";
this.listView1.Items.Add(new ListViewItem(s));
s[0] = "李四";
s[1] = "男";
s[2] = "25";
s[3] = "SQL Server";
s[4] = "Mon";
this.listView1.Items.Add(new ListViewItem(s));
s[0] = "王五";
s[1] = "男";
s[2] = "23";
s[3] = "VB";
s[4] = "Tue";
this.listView1.Items.Add(new ListViewItem(s));
s[0] = "赵六";
s[1] = "女";
s[2] = "22";
s[3] = "Lotus";
s[4] = "Wed";
this.listView1.Items.Add(new ListViewItem(s));
///////////////////////////
///other common attributs
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listView1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.listView1.FullRowSelect = true;
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(448, 273);
this.listView1.TabIndex = 0;
this.listView1.View = System.Windows.Forms.View.Details;
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.listView1});
双击需要编辑的单元,如果该列为ALAN_ListViewColumnStyle.ReadOnly 则没有变化;如果该列为ALAN_ListViewColumnStyle.EditBox则出现文本框;如果该列为ALAN_ListViewColumnStyle.ComboBox则出现组合框,如下图:
图1 EditBox风格
图2 ComboBox风格
对该文的评论 人气:588
ruanyuping (2003-11-3 14:06:26)
有没有源码下载啊
steeven (2003-10-31 16:47:48)
能不能解释一下实现方式和要点.一堆代码没时间看啊