简单的控件类型(C控件美化之路9)

简单的控件类型(C控件美化之路9)(1)

简单的控件类型(C控件美化之路9)(2)

简单的控件类型(C控件美化之路9)(3)

ListBox 在C# winform编程中,使用的比较多,用途也很广,今天带大家一步步的美化ListBox控件。

本文主要实现。

1.奇数行与偶数行颜色交替。

2.选中行颜色。

3.鼠标移动停留行颜色。

4.增加序号

5.增加单选框显示。

前面的若干文章,已经讲解了重绘等一些技巧,这篇文章,理解内容相对比较多,看的小伙伴可以收藏,若碰到问题,欢迎在下方留言。

重绘第一步依然

新建一个类 ,继承ListBox

简单的控件类型(C控件美化之路9)(4)

文中写的部分在之前文章提到过,本文不做详细描述,主要就是减少闪烁,双缓存等。

构造函数中内容

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; }

ControlStyles.UserPaint 此项是所有内容都由用户绘制,一般不用为true。若是需要全部用户自定义绘制。高级重绘,应当此项勾选,本文主要是绘制项,就不把此项设置为true。

私有属性

#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=20; #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("Wen"), Description("设置单项高度"), DefaultValue(20)] public new int ItemHeight { get => itemHeight; set { base.ItemHeight = value; itemHeight = value; } } #endregion

此处贴一个常用方法颜色获取brush,当然此方法一般可以直接写在代码中没必要专门用一个方法,本文主要便于理解,一般在编程中,都会用using。本文不演示,后续文章转成解释using的使用。

#region 颜色获取Brush private Brush GetBrush(string b) { return new SolidBrush(ColorTranslator.FromHtml(b)); } private Brush GetBrush(Color c) { return new SolidBrush(c); } #endregion

执行重绘必要因素

ListBox 由于目前重绘只重绘项,不直接全部重绘,所以只需要重写OnDrawItem

贴代码块

//重绘指定项 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); } }

ItemDraw由于重绘重绘可利用代码较多,本文主要用了一个方法来实现。

//刷新指定项目 private void ItemDraw(int index, Graphics g, Rectangle rec, Color c, DrawItemEventArgs e) { ControlHelper.SetGDIHigh(g); g.FillRectangle(GetBrush(c), rec); Brush brush = GetBrush(e.ForeColor); int radioWidth = 0; if (RadioBox) { radioWidth = 20; Pen pen = new Pen(Color.Gray, 3); 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 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)); }

刷新指定索引项

//刷新指定索引项 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)); }

到目前为止重绘已经完成,当然在常用中一般还需要增加项点击事件,可以按照需求自写一个委托事件。

写一个委托事件。 贴完整代码块

public delegate void WenListBoxEventHandler(object sender, WenListBoxEventArgs e); public class WenListBoxEventArgs : EventArgs { public WenListBoxEventArgs(object item) { this.Item = item; } public object Item { get; set; } }

委托 项被点击事件

#region 委托事件 [Category("Wen"), Description("项被点击事件")] public event WenListBoxEventHandler ItemClick; #endregion

至此一个完整listbox重绘已经完成。

简单的控件类型(C控件美化之路9)(5)

简单的控件类型(C控件美化之路9)(6)

至此一个ListBox重绘完成。

关注文林软控。带你用C# 美化.NET控件。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页