winform下重画ListBox
2020-12-13 14:25
标签:des winform style blog http io color os ar Windows Forms是由Win32 API封装的开发组件,最初是为了替代mfc,但却没有体现与Model View Controller架构对应的特色,进而在.net framework 3.0中推出了wpf,富控件数据显示方面,利用模板功能轻松实现。 在winform下要想自定义一些用户控件,就需要运用的2D绘画类。下图我们为ListBox重新排列了数据显示方式,并为每一个item加入了删除按钮。 首先我们设计一个承载数据的类ListBoxItem。 然后我们再为ListBox写一个用于展现数据的数据源ListBoxItemCollection,这里实现了迭代和集合操作接口,可以根据需要扩展数据操作方法。 下面可以为工程new一个新项——自定义控件,命名为UserListBox。 这里有几个地方要说明一下,首先在默认构造函数里面的参数: DrawMode.OwnerDrawVariable启用控件重绘功能。 DoubleBuffer开启后避免复杂绘画造成窗体闪烁,这个缓冲的原理是将绘画操作放在内存里操作,完成后才会复制到图形界面上,进而避免的闪烁。 OnPaint进行了重写,这个方法是根据pc屏幕分辨率刷新频率来执行的,会不断的重复执行,进而持久化图形界面。 Invalidate方法,会立即刷新UI。 Item上的按钮事件,是通过ListBox的click事件,取到鼠标的在界面上的定位,调用相对应的方法。 winform下重画ListBox 标签:des winform style blog http io color os ar 原文地址:http://www.cnblogs.com/yuefei/p/4062998.html 1 public class ListBoxItem : IDisposable
2 {
3 public Guid Id { get; set; }
4
5 public string Name { get; set; }
6
7 public string IP { get; set; }
8
9 public string Mac { get; set; }
10
11 [System.ComponentModel.DefaultValue(typeof(System.Drawing.Image), "null")]
12 public System.Drawing.Image Image { get; set; }
13
14 public bool IsFocus { get; set; }
15
16 public ListBoxItem() { }
17
18 public ListBoxItem(Guid id, string name, string ip, string mac, System.Drawing.Image image)
19 {
20 this.Id = id;
21 this.Name = name;
22 this.IP = ip;
23 this.Mac = mac;
24 this.Image = image;
25 this.IsFocus = false;
26 }
27
28 public void Dispose()
29 {
30 this.Image = null;
31 }
32 }
[System.ComponentModel.ListBindable(false)]
public class ListBoxItemCollection : IList, ICollection, IEnumerable
{
private UserListBox m_owner;
public ListBoxItemCollection(UserListBox owner)
{
this.m_owner = owner;
}
internal UserListBox Owner
{
get { return this.m_owner; }
}
#region override
public ListBoxItem this[int index]
{
get { return Owner.OldItemSource[index] as ListBoxItem; }
set { Owner.OldItemSource[index] = value; }
}
public int Count
{
get { return Owner.OldItemSource.Count; }
}
public bool IsReadOnly
{
get { return Owner.OldItemSource.IsReadOnly; }
}
public int Add(ListBoxItem item)
{
if (item == null)
{
throw new ArgumentException("item is null");
}
return Owner.OldItemSource.Add(item);
}
public void AddRange(ListBoxItem[] items)
{
Owner.OldItemSource.AddRange(items);
}
public void Clear()
{
if (Owner.OldItemSource.Count > 0)
{
Owner.OldItemSource.Clear();
}
}
public bool Contains(ListBoxItem item)
{
bool rst = false;
foreach (ListBoxItem oldItem in Owner.OldItemSource)
{
if (oldItem.Id == item.Id)
{
rst = true;
break;
}
}
return rst;
}
public void CopyTo(ListBoxItem[] destination, int arrayIndex)
{
Owner.OldItemSource.CopyTo(destination, arrayIndex);
}
public int IndexOf(ListBoxItem item)
{
return Owner.OldItemSource.IndexOf(item);
}
public void Insert(int index, ListBoxItem item)
{
if (item == null)
{
throw new ArgumentException("item is null");
}
Owner.OldItemSource.Insert(index, item);
}
public void Remove(ListBoxItem item)
{
Owner.OldItemSource.Remove(item);
}
public void RemoveAt(int index)
{
Owner.OldItemSource.RemoveAt(index);
}
public IEnumerator GetEnumerator()
{
return Owner.OldItemSource.GetEnumerator();
}
int IList.Add(object value)
{
if (!(value is ListBoxItem))
{
throw new ArgumentException();
}
return Add(value as ListBoxItem);
}
void IList.Clear()
{
Clear();
}
bool IList.Contains(object value)
{
return Contains(value as ListBoxItem);
}
int IList.IndexOf(object value)
{
return IndexOf(value as ListBoxItem);
}
void IList.Insert(int index, object value)
{
if (!(value is ListBoxItem))
{
throw new ArgumentException();
}
Insert(index, value as ListBoxItem);
}
bool IList.IsFixedSize
{
get { return false; }
}
bool IList.IsReadOnly
{
get { return IsReadOnly; }
}
void IList.Remove(object value)
{
Remove(value as ListBoxItem);
}
void IList.RemoveAt(int index)
{
RemoveAt(index);
}
object IList.this[int index]
{
get { return this[index]; }
set
{
if (!(value is ListBoxItem))
{
throw new ArgumentException();
}
this[index] = value as ListBoxItem;
}
}
void ICollection.CopyTo(Array array, int index)
{
CopyTo((ListBoxItem[])array, index);
}
int ICollection.Count
{
get { return Count; }
}
bool ICollection.IsSynchronized
{
get { return false; }
}
object ICollection.SyncRoot
{
get { return false; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region extention
public ListBoxItem FindByMac(string mac)
{
foreach (ListBoxItem item in Owner.OldItemSource)
{
if (item.Mac == mac)
{
return item;
}
}
return null;
}
#endregion
}
1 public partial class UserListBox : ListBox
2 {
3 public ListBoxItem mouseItem;
4 private ListBoxItemCollection m_Items;
5
6 public UserListBox() : base()
7 {
8 InitializeComponent();
9
10 m_Items = new ListBoxItemCollection(this);
11
12 base.DrawMode = DrawMode.OwnerDrawVariable;
13 this.SetStyle(ControlStyles.UserPaint, true);
14 this.SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
15 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 双缓冲
16 this.SetStyle(ControlStyles.ResizeRedraw, true); // 调整大小时重绘
17 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
18 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); // 开启控件透明
19 }
20
21 public new ListBoxItemCollection Items
22 {
23 get { return m_Items; }
24 }
25
26 internal ListBox.ObjectCollection OldItemSource
27 {
28 get { return base.Items; }
29 }
30
31 protected override void OnPaint(PaintEventArgs e)
32 {
33 Graphics g = e.Graphics;
34
35 // you can set SeletedItem background
36 if (this.Focused && this.SelectedItem != null)
37 {
38 }
39
40 for (int i = 0; i )
41 {
42 Rectangle bounds = this.GetItemRectangle(i);
43
44 if (mouseItem == Items[i])
45 {
46 Color leftColor = Color.FromArgb(200, 192, 224, 248);
47 using (SolidBrush brush = new SolidBrush(leftColor))
48 {
49 g.FillRectangle(brush, new Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height));
50 }
51
52 Color rightColor = Color.FromArgb(252, 233, 161);
53 using (SolidBrush brush = new SolidBrush(rightColor))
54 {
55 g.FillRectangle(brush, new Rectangle(bounds.Width - 40, bounds.Y, 40, bounds.Height));
56 }
57 }
58
59 int fontLeft = bounds.Left + 40 + 15;
60 System.Drawing.Font font = new System.Drawing.Font("微软雅黑", 9);
61 g.DrawString(Items[i].Name, font, new SolidBrush(this.ForeColor), fontLeft, bounds.Top + 5);
62 g.DrawString(Items[i].IP, font, new SolidBrush(Color.FromArgb(128, 128, 128)), fontLeft, bounds.Top + 20);
63 g.DrawString(Items[i].Mac, font, new SolidBrush(Color.FromArgb(128, 128, 128)), fontLeft, bounds.Top + 35);
64
65 if (Items[i].Image != null)
66 {
67 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
68 g.DrawImage(Items[i].Image, new Rectangle(bounds.X + 5, (bounds.Height - 40) / 2 + bounds.Top, 40, 40));
69 }
70 g.DrawImage(Properties.Resources.error, new Rectangle(bounds.Width - 28, (bounds.Height - 16) / 2 + bounds.Top, 16, 16));
71 }
72 base.OnPaint(e);
73 }
74
75 protected override void OnMeasureItem(MeasureItemEventArgs e)
76 {
77 base.OnMeasureItem(e);
78 if (Items.Count > 0)
79 {
80 ListBoxItem item = Items[e.Index];
81 e.ItemHeight = 54;
82 }
83
84 }
85
86 protected override void OnSelectedIndexChanged(EventArgs e)
87 {
88 base.OnSelectedIndexChanged(e);
89 }
90
91 protected override void OnMouseMove(MouseEventArgs e)
92 {
93 base.OnMouseMove(e);
94 for (int i = 0; i )
95 {
96 Rectangle bounds = this.GetItemRectangle(i);
97 Rectangle deleteBounds = new Rectangle(bounds.Width - 28, (bounds.Height - 16) / 2 + bounds.Top, 16, 16);
98
99 if (bounds.Contains(e.X, e.Y))
100 {
101 if (Items[i] != mouseItem)
102 {
103 mouseItem = Items[i];
104 }
105
106 if (deleteBounds.Contains(e.X, e.Y))
107 {
108 mouseItem.IsFocus = true;
109 this.Cursor = Cursors.Hand;
110 }
111 else
112 {
113 mouseItem.IsFocus = false;
114 this.Cursor = Cursors.Arrow;
115 }
116
117 this.Invalidate();
118 break;
119 }
120 }
121 }
122
123 protected override void OnMouseClick(MouseEventArgs e)
124 {
125 base.OnMouseClick(e);
126 if (mouseItem.IsFocus)
127 {
128 ListBoxItem deleteItem = mouseItem;
129 if(MessageBox.Show("confirm to delete", "", MessageBoxButtons.OKCancel) == DialogResult.OK)
130 {
131 this.Items.Remove(deleteItem);
132 }
133 }
134 }
135
136 protected override void OnMouseLeave(EventArgs e)
137 {
138 base.OnMouseLeave(e);
139 this.mouseItem = null;
140 this.Invalidate();
141 }
142 }