winform下重画ListBox
Posted belx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winform下重画ListBox相关的知识,希望对你有一定的参考价值。
原文https://www.cnblogs.com/yuefei/p/4062998.html
修改
自定义控件
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using winform下重画ListBox.Properties; namespace winform下重画ListBox { public partial class UserListBox : ListBox { private readonly ListBoxItemCollection m_Items; public ListBoxItem mouseItem; public UserListBox() { InitializeComponent(); m_Items = new ListBoxItemCollection(this); base.DrawMode = DrawMode.OwnerDrawVariable; SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲 SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // 双缓冲 SetStyle(ControlStyles.ResizeRedraw, true); // 调整大小时重绘 SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. SetStyle(ControlStyles.SupportsTransparentBackColor, true); // 开启控件透明 } public new ListBoxItemCollection Items { get { return m_Items; } } internal ObjectCollection OldItemSource { get { return base.Items; } } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; // you can set SeletedItem background if (Focused && SelectedItem != null) { } for (int i = 0; i < Items.Count; i++) { Rectangle bounds = GetItemRectangle(i); if (mouseItem == Items[i]) { Color leftColor = Color.FromArgb(200, 192, 224, 248); using (var brush = new SolidBrush(leftColor)) { g.FillRectangle(brush, new Rectangle(bounds.X, bounds.Y, bounds.Width, bounds.Height)); } Color rightColor = Color.FromArgb(252, 233, 161); using (var brush = new SolidBrush(rightColor)) { g.FillRectangle(brush, new Rectangle(bounds.Width - 40, bounds.Y, 40, bounds.Height)); } } int fontLeft = bounds.Left + 40 + 15; var font = new Font("微软雅黑", 9); g.DrawString(Items[i].Name, font, new SolidBrush(ForeColor), fontLeft, bounds.Top + 5); g.DrawString(Items[i].IP, font, new SolidBrush(Color.FromArgb(128, 128, 128)), fontLeft, bounds.Top + 20); g.DrawString(Items[i].Mac, font, new SolidBrush(Color.FromArgb(128, 128, 128)), fontLeft, bounds.Top + 35); if (Items[i].Image != null) { g.InterpolationMode = InterpolationMode.HighQualityBilinear; g.DrawImage(Items[i].Image, new Rectangle(bounds.X + 5, (bounds.Height - 40)/2 + bounds.Top, 40, 40)); } g.DrawImage(Resources.delete, new Rectangle(bounds.Width - 28, (bounds.Height - 16)/2 + bounds.Top, 16, 16)); } base.OnPaint(e); } protected override void OnMeasureItem(MeasureItemEventArgs e) { base.OnMeasureItem(e); if (Items.Count > 0) { ListBoxItem item = Items[e.Index]; e.ItemHeight = 54; } } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); for (int i = 0; i < Items.Count; i++) { Rectangle bounds = GetItemRectangle(i); var deleteBounds = new Rectangle(bounds.Width - 28, (bounds.Height - 16)/2 + bounds.Top, 16, 16); if (bounds.Contains(e.X, e.Y)) { if (Items[i] != mouseItem) { mouseItem = Items[i]; } if (deleteBounds.Contains(e.X, e.Y)) { mouseItem.IsFocus = true; Cursor = Cursors.Hand; } else { mouseItem.IsFocus = false; Cursor = Cursors.Arrow; } Invalidate(); break; } } } protected override void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); if (mouseItem.IsFocus) { ListBoxItem deleteItem = mouseItem; if (MessageBox.Show("confirm to delete", "", MessageBoxButtons.OKCancel) == DialogResult.OK) { Items.Remove(deleteItem); } } } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); mouseItem = null; Invalidate(); } } //首先我们设计一个承载数据的类ListBoxItem。 public class ListBoxItem : IDisposable { public ListBoxItem() { } public ListBoxItem(Guid id, string name, string ip, string mac, Image image) { Id = id; Name = name; IP = ip; Mac = mac; Image = image; IsFocus = false; } public Guid Id { get; set; } public string Name { get; set; } public string IP { get; set; } public string Mac { get; set; } [DefaultValue(typeof (Image), "null")] public Image Image { get; set; } public bool IsFocus { get; set; } public void Dispose() { Image = null; } } //然后我们再为ListBox写一个用于展现数据的数据源ListBoxItemCollection,这里实现了迭代和集合操作接口,可以根据需要扩展数据操作方法。 [ListBindable(false)] public class ListBoxItemCollection : IList, ICollection, IEnumerable { private readonly UserListBox m_owner; public ListBoxItemCollection(UserListBox owner) { m_owner = owner; } internal UserListBox Owner { get { return 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; } } 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(); } 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(); } #endregion #region extention public ListBoxItem FindByMac(string mac) { foreach (ListBoxItem item in Owner.OldItemSource) { if (item.Mac == mac) { return item; } } return null; } #endregion } }
测试
using System; using System.Windows.Forms; using winform下重画ListBox.Properties; namespace winform下重画ListBox { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //ListBoxItem(Guid id, string name, string ip, string mac, Image image) listBox1.Items.Add(new ListBoxItem(Guid.NewGuid(), "Name", "192.168.0.1", "Mac", Resources.delete)); listBox1.Items.Add(new ListBoxItem(Guid.NewGuid(), "Name", "192.168.0.1", "Mac", Resources.delete)); } } }
以上是关于winform下重画ListBox的主要内容,如果未能解决你的问题,请参考以下文章