using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace DPumpHydr.WinFrmUI.WenSkin.Controls { public class WenListBox : ListBox { public WenListBox() { base.SetStyle( //ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); base.UpdateStyles(); this.DrawMode = DrawMode.OwnerDrawFixed; this.IntegralHeight = false; ItemHeight = 23; } #region 委托事件 [Category("Wen"), Description("项被点击事件")] public event WenListBoxEventHandler ItemClick; #endregion #region 私有属性 //选中项改变之前的选中项索引 private int selectBefore = -1; private int MouseItemIndex; private bool line = true; private bool radioBox = true; private Color oneRowColor = Color.DeepSkyBlue; private Color towRowColor = Color.Aquamarine; private Color selectedRowColor = Color.DarkCyan; private Color mouseMoveRowColor = Color.Cyan; private int itemHeight; #endregion #region 公有属性 [Category("Wen"), Description("是否增加序号"), DefaultValue(true)] public bool Line { get => line; set { line = value; this.Invalidate(); } } [Category("Wen"), Description("是否增加选框"), DefaultValue(true)] public bool RadioBox { get => radioBox; set { radioBox = value; this.Invalidate(); } } [Category("Wen"), Description("奇数行颜色"), DefaultValue(typeof(Color), "DeepSkyBlue")] public Color OneRowColor { get => oneRowColor; set { oneRowColor = value; this.Invalidate(); } } [Category("Wen"), Description("偶数行颜色"), DefaultValue(typeof(Color), "Aquamarine")] public Color TowRowColor { get => towRowColor; set { towRowColor = value; this.Invalidate(); } } [Category("Wen"), Description("选中颜色"), DefaultValue(typeof(Color), "DarkCyan")] public Color SelectedRowColor { get => selectedRowColor; set { selectedRowColor = value; this.Invalidate(); } } [Category("Wen"), Description("鼠标移动行颜色"), DefaultValue(typeof(Color), "Cyan")] public Color MouseMoveRowColor { get => mouseMoveRowColor; set { mouseMoveRowColor = value; this.Invalidate(); } } #endregion #region 数据绑定 [Category("WenData"), Description("绑定数据列"), DefaultValue(null)] public string ColumnName { get; set; } private object dataSource { get; set; } [Browsable(false)] public new object DataSource { get => dataSource; set { if (value != null) { dataSource = value; DataBind(); } } } private void DataBind() { if (dataSource == null) return; this.Items.Clear(); //分类数据绑定 switch (dataSource) { case DataSet ds: DataBindDataTable(ds.Tables[0]); break; case DataTable dt: DataBindDataTable(dt); break; case IList ilist: if (string.IsNullOrWhiteSpace(ColumnName)) { foreach (var li in ilist) { List propertyInfos = new List(li.GetType().GetProperties()); string value = propertyInfos.Find(a => a.Name.ToUpper() == ColumnName.ToUpper())?.GetValue(li, null)?.ToString(); Items.Add(value); } } else { foreach (var li in ilist) { string value = li.GetType().GetProperties()[0].GetValue(li, null)?.ToString(); Items.Add(value); } } break; default: break; } //绑定数据 void DataBindDataTable(DataTable dt) { if (string.IsNullOrWhiteSpace(ColumnName)) foreach (DataRow dr in dt.Rows) { Items.Add(dr[0]); } else foreach (DataRow dr in dt.Rows) { Items.Add(dr[ColumnName]); } } } #endregion #region 重置属性或者重写属性 [Category("Wen"), Description("设置单项高度"), DefaultValue(23)] public new int ItemHeight { get => itemHeight; set { base.ItemHeight = value; itemHeight = value; } } #endregion #region 执行重绘 //重绘指定项 protected override void OnDrawItem(DrawItemEventArgs e) { //base.OnDrawItem(e); if (Items.Count == 0 || e.Index < 0) return; Graphics g = e.Graphics; Rectangle rec = GetItemRectangle(e.Index); if (GetSelected(e.Index)) { rec.Inflate(0, -2); ItemDraw(e.Index, g, rec, SelectedRowColor, e); } else if (e.Index == MouseItemIndex) { ItemDraw(e.Index, g, rec, MouseMoveRowColor, e); } else if (e.Index % 2 != 1) { ItemDraw(e.Index, g, rec, OneRowColor, e); } else { ItemDraw(e.Index, g, rec, TowRowColor, e); } } //刷新指定项目 private void ItemDraw(int index, Graphics g, Rectangle rec, Color c, DrawItemEventArgs e) { ControlHelper.SetGDIHigh(g); using Brush backColor = new SolidBrush(c); g.FillRectangle(backColor, rec); using Brush brush = new SolidBrush(e.ForeColor); int radioWidth = 0; if (RadioBox) { radioWidth = 20; g.DrawEllipse(new Pen(brush) { Width = 2 }, new Rectangle(rec.X, (ItemHeight - 15) / 2 + rec.Y, 15, 15)); if (GetSelected(index)) g.FillEllipse(brush, new Rectangle(rec.X + 5, (ItemHeight - 5) / 2 + rec.Y, 5, 5)); } //绘制文字 if (Line) { Rectangle recLine = new Rectangle(rec.X + radioWidth, rec.Y, 50 - radioWidth, this.ItemHeight); Rectangle recText = new Rectangle(rec.X + 50, rec.Y, rec.Width - 50, this.ItemHeight); g.DrawString((index + 1).ToString(), Font, brush, recLine, ControlHelper.StringConters); g.DrawString(Items[index]?.ToString(), Font, brush, recText, ControlHelper.StringConters); } else { Rectangle recText = new Rectangle(rec.X + radioWidth, rec.Y, rec.Width - radioWidth, this.ItemHeight); g.DrawString(Items[index]?.ToString(), Font, brush, recText, ControlHelper.StringConters); } } //鼠标移动 protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); int index = IndexFromPoint(e.Location); if (index < 0) return; if (MouseItemIndex != index) { int indexBefore = MouseItemIndex; MouseItemIndex = index; this.RefreshItem(index); this.RefreshItem(indexBefore); } } //刷新指定索引项 protected override void RefreshItem(int index) { if (index < 0 || Items.Count == 0) return; Graphics g = CreateGraphics(); Rectangle rec = GetItemRectangle(index); g.SetClip(new Rectangle(rec.X, rec.Y + 1, rec.Width, rec.Height - 1)); if (SelectedIndex == index) OnDrawItem(new DrawItemEventArgs(g, Font, rec, index, DrawItemState.Selected, Color.White, this.SelectedRowColor)); else OnDrawItem(new DrawItemEventArgs(g, Font, rec, index, DrawItemState.None, this.ForeColor, this.SelectedRowColor)); } //鼠标移开事件 protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); int index = MouseItemIndex; MouseItemIndex = -1; RefreshItem(index); } //选中索引变化 protected override void OnSelectedIndexChanged(EventArgs e) { base.OnSelectedIndexChanged(e); if (selectBefore != -1) { RefreshItem(selectBefore); } selectBefore = SelectedIndex; object item = this.SelectedItem; ItemClick?.Invoke(this, new WenListBoxEventArgs(item)); } #endregion } public delegate void WenListBoxEventHandler(object sender, WenListBoxEventArgs e); public class WenListBoxEventArgs : EventArgs { public WenListBoxEventArgs(object item) { this.Item = item; } public object Item { get; set; } } }