控件功能:
1、列表头颜色可变
2、列表线颜色可变
3、列表行背景色交替变化
4、行选中色可调
5、单元格双击可编辑(第一列处存在bug)
大致效果
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace ListViewPro
{
public partial class ListViewEx : ListView
{
private Color _rowBackColor1 = Color.White;
private Color _rowBackColor2 = Color.FromArgb(255,255,225);
private Color _selectedColor = Color.FromArgb(49, 106, 196);
private Color _headColor = Color.FromArgb(236, 233, 216);
private Color _borderColor = Color.FromArgb(236,233,216);
private bool _editable = true;
private TextBox m_tb;
public ListViewEx() : base()
{
base.OwnerDraw = true;
m_tb = new TextBox();
m_tb.Multiline = true;
m_tb.Visible = false;
this.Controls.Add(m_tb);
}
[DefaultValue(typeof(Color), "White")]
public Color RowBackColor1
{
get { return _rowBackColor1; }
set
{
_rowBackColor1 = value;
base.Invalidate();
}
}
[DefaultValue(typeof(Color), "info")]
public Color RowBackColor2
{
get { return _rowBackColor2; }
set
{
_rowBackColor2 = value;
base.Invalidate();
}
}
[DefaultValue(typeof(Color), "Highlight")]
public Color SelectedColor
{
get { return _selectedColor; }
set
{
_selectedColor = value;
base.Invalidate();
}
}
[DefaultValue(typeof(Color), "Control")]
public Color HeadColor
{
get { return _headColor; }
set
{
_headColor = value;
base.Invalidate();
}
}
[DefaultValue(typeof(Color), "Control")]
public Color BorderColor
{
get { return _borderColor; }
set
{
_borderColor = value;
base.Invalidate();
}
}
[DefaultValue(typeof(bool), "true")]
public bool Editable
{
get { return _editable; }
set { _editable = value; }
}
protected override void OnDrawColumnHeader(
DrawListViewColumnHeaderEventArgs e)
{
base.OnDrawColumnHeader(e);
Graphics g = e.Graphics;
Rectangle bounds = e.Bounds;
Color baseColor = _headColor;
Color borderColor = _borderColor;
RenderBackgroundInternal(
g,
bounds,
baseColor,
borderColor,
0.35f,
true,
LinearGradientMode.Vertical);
TextFormatFlags flags = GetFormatFlags(e.Header.TextAlign);
Rectangle textRect = new Rectangle(
bounds.X + 3,
bounds.Y,
bounds.Width - 6,
bounds.Height);
if (e.Header.ImageList != null)
{
Image image = e.Header.ImageIndex == -1 ?
null : e.Header.ImageList.Images[e.Header.ImageIndex];
if (image != null)
{
Rectangle imageRect = new Rectangle(
bounds.X + 3,
bounds.Y + 2,
bounds.Width - 4,
bounds.Height - 4);
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImage(image, imageRect);
textRect.X = imageRect.Right + 3;
textRect.Width -= imageRect.Width;
}
}
TextRenderer.DrawText(
g,
e.Header.Text,
e.Font,
textRect,
e.ForeColor,
flags);
}
protected override void OnDrawItem(DrawListViewItemEventArgs e)
{
base.OnDrawItem(e);
if (View != View.Details)
{
e.DrawDefault = true;
}
}
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
base.OnDrawSubItem(e);
if (View != View.Details)
{
return;
}
if (e.ItemIndex == -1)
{
return;
}
Rectangle bounds = e.Bounds;
ListViewItemStates itemState = e.ItemState;
Graphics g = e.Graphics;
Pen p = new Pen(_borderColor);
e.Graphics.DrawRectangle(p, bounds);
if ((itemState & ListViewItemStates.Selected)
== ListViewItemStates.Selected)
{
bounds.Height--;
Color baseColor = _selectedColor;
Color borderColor = _selectedColor;
Color innerBorderColor = _selectedColor;
RenderBackgroundInternal(
g,
bounds,
baseColor,
borderColor,
0.35f,
true,
LinearGradientMode.Vertical);
bounds.Height++;
}
else
{
Color backColor = e.ItemIndex % 2 == 0 ?
_rowBackColor1 : _rowBackColor2;
using (SolidBrush brush = new SolidBrush(backColor))
{
Rectangle newRect = bounds;
newRect.X++;
newRect.Width -= 2;
newRect.Y++;
newRect.Height -= 2;
g.FillRectangle(brush, newRect);
}
}
TextFormatFlags flags = GetFormatFlags(e.Header.TextAlign);
if (e.ColumnIndex == 0)
{
if (e.Item.ImageList == null)
{
e.DrawText(flags);
return;
}
Image image = e.Item.ImageIndex == -1 ?
null : e.Item.ImageList.Images[e.Item.ImageIndex];
if (image == null)
{
e.DrawText(flags);
return;
}
Rectangle imageRect = new Rectangle(
bounds.X + 4,
bounds.Y + 2,
bounds.Height - 4,
bounds.Height - 4);
g.DrawImage(image, imageRect);
Rectangle textRect = new Rectangle(
imageRect.Right + 3,
bounds.Y,
bounds.Width - imageRect.Right - 3,
bounds.Height);
TextRenderer.DrawText(
g,
e.Item.Text,
e.Item.Font,
textRect,
e.Item.ForeColor,
flags);
return;
}
e.DrawText(flags);
}
protected TextFormatFlags GetFormatFlags(HorizontalAlignment align)
{
TextFormatFlags flags =
TextFormatFlags.EndEllipsis |
TextFormatFlags.VerticalCenter;
switch (align)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.HorizontalCenter;
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.Right;
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.Left;
break;
}
return flags;
}
internal void RenderBackgroundInternal(
Graphics g,
Rectangle rect,
Color baseColor,
Color borderColor,
float basePosition,
bool drawBorder,
LinearGradientMode mode)
{
using(Brush brush = new SolidBrush(baseColor))
{
g.FillRectangle(brush, rect);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)(rect.Width * basePosition);
}
using (SolidBrush brushAlpha =
new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
this.m_tb.Visible = false;
base.OnSelectedIndexChanged(e);
}
protected override void OnDoubleClick(EventArgs e)
{
if(_editable)
{
Point tmpPoint = this.PointToClient(Cursor.Position);
ListViewItem.ListViewSubItem subitem = this.HitTest(tmpPoint).SubItem;
ListViewItem item = this.HitTest(tmpPoint).Item;
if (subitem != null)
{
EditItem(subitem);
}
}
base.OnDoubleClick(e);
}
private void EditItem(ListViewItem.ListViewSubItem subItem)
{
if (this.SelectedItems.Count <= 0)
{
return;
}
Rectangle _rect = subItem.Bounds;
m_tb.Bounds = _rect;
m_tb.BringToFront();
m_tb.Text = subItem.Text;
m_tb.Leave += new EventHandler(tb_Leave);
m_tb.TextChanged += new EventHandler(m_tb_TextChanged);
m_tb.KeyPress += new KeyPressEventHandler(m_tb_KeyPress);
m_tb.Visible = true;
m_tb.Tag = subItem;
m_tb.Select();
}
private void tb_Leave(object sender, EventArgs e)
{
m_tb.TextChanged -= new EventHandler(m_tb_TextChanged);
m_tb.KeyPress -= new KeyPressEventHandler(m_tb_KeyPress);
(sender as TextBox).Visible = false;
}
private void m_tb_TextChanged(object sender, EventArgs e)
{
if ((sender as TextBox).Tag is ListViewItem.ListViewSubItem)
{
(this.m_tb.Tag as ListViewItem.ListViewSubItem).Text = this.m_tb.Text;
}
}
private void m_tb_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
{
m_tb.TextChanged -= new EventHandler(m_tb_TextChanged);
m_tb.Leave -= new EventHandler(tb_Leave);
(sender as TextBox).Visible = false;
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x115 || m.Msg == 0x114)
{
this.m_tb.Visible = false;
}
base.WndProc(ref m);
}
}
}
以上完全参考一下两篇文章所作,
1、http://hi.baidu.com/%B0%D7%D4%C6%D2%BB%C2%C6/blog/item/da42bac3e3c02d5db219a80a.html
2、http://www.cnblogs.com/wanfei/archive/2010/04/23/1718498.html
若有不对之处,请大家多多指正