(三十六)c#Winform自定义控件-步骤控件
程序员文章站
2024-02-01 17:32:04
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果觉得写的还行,请点个 star 支持一下吧 欢迎前来交流探讨: 企鹅群568015492 目录 ......
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
开源地址:
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
目录
准备工作
也没什么可准备的了
开始
添加一个用户控件,命名ucstep
来点属性
1 public event eventhandler indexchecked; 2 3 private color m_stepbackcolor = color.fromargb(100, 100, 100); 4 /// <summary> 5 /// 步骤背景色 6 /// </summary> 7 [description("步骤背景色"), category("自定义")] 8 public color stepbackcolor 9 { 10 get { return m_stepbackcolor; } 11 set { m_stepbackcolor = value; } 12 } 13 14 private color m_stepforecolor = color.fromargb(255, 85, 51); 15 /// <summary> 16 /// 步骤前景色 17 /// </summary> 18 [description("步骤前景色"), category("自定义")] 19 public color stepforecolor 20 { 21 get { return m_stepforecolor; } 22 set { m_stepforecolor = value; } 23 } 24 25 private color m_stepfontcolor = color.white; 26 /// <summary> 27 /// 步骤文字颜色 28 /// </summary> 29 [description("步骤文字景色"), category("自定义")] 30 public color stepfontcolor 31 { 32 get { return m_stepfontcolor; } 33 set { m_stepfontcolor = value; } 34 } 35 36 private int m_stepwidth = 35; 37 /// <summary> 38 /// 步骤宽度 39 /// </summary> 40 [description("步骤宽度景色"), category("自定义")] 41 public int stepwidth 42 { 43 get { return m_stepwidth; } 44 set { m_stepwidth = value; } 45 } 46 47 private string[] m_steps = new string[] { "step1", "step2", "step3" }; 48 49 [description("步骤"), category("自定义")] 50 public string[] steps 51 { 52 get { return m_steps; } 53 set 54 { 55 if (m_steps == null || m_steps.length <= 1) 56 return; 57 m_steps = value; 58 refresh(); 59 } 60 } 61 62 private int m_stepindex = 0; 63 64 [description("步骤位置"), category("自定义")] 65 public int stepindex 66 { 67 get { return m_stepindex; } 68 set 69 { 70 if (m_stepindex >= steps.length) 71 return; 72 m_stepindex = value; 73 refresh(); 74 if (indexchecked != null) 75 { 76 indexchecked(this, null); 77 } 78 } 79 }
重绘
1 protected override void onpaint(painteventargs e) 2 { 3 base.onpaint(e); 4 var g = e.graphics; 5 g.smoothingmode = smoothingmode.antialias; //使绘图质量最高,即消除锯齿 6 g.interpolationmode = interpolationmode.highqualitybicubic; 7 g.compositingquality = compositingquality.highquality; 8 9 if (m_steps != null && m_steps.length > 0) 10 { 11 system.drawing.sizef sizefirst = g.measurestring(m_steps[0], this.font); 12 int y = (this.height - m_stepwidth - 10 - (int)sizefirst.height) / 2; 13 if (y < 0) 14 y = 0; 15 16 int inttxty = y + m_stepwidth + 10; 17 int intleft = 0; 18 if (sizefirst.width > m_stepwidth) 19 { 20 intleft = (int)(sizefirst.width - m_stepwidth) / 2 + 1; 21 } 22 23 int intright = 0; 24 system.drawing.sizef sizeend = g.measurestring(m_steps[m_steps.length - 1], this.font); 25 if (sizeend.width > m_stepwidth) 26 { 27 intright = (int)(sizeend.width - m_stepwidth) / 2 + 1; 28 } 29 30 int intsplitwidth = 20; 31 intsplitwidth = (this.width - m_steps.length - (m_steps.length * m_stepwidth) - intright) / (m_steps.length - 1); 32 if (intsplitwidth < 20) 33 intsplitwidth = 20; 34 35 for (int i = 0; i < m_steps.length; i++) 36 { 37 #region 画圆,横线 38 g.fillellipse(new solidbrush(m_stepbackcolor), new rectangle(new point(intleft + i * (m_stepwidth + intsplitwidth), y), new size(m_stepwidth, m_stepwidth))); 39 40 if (m_stepindex > i) 41 { 42 g.fillellipse(new solidbrush(m_stepforecolor), new rectangle(new point(intleft + i * (m_stepwidth + intsplitwidth) + 2, y + 2), new size(m_stepwidth - 4, m_stepwidth - 4))); 43 44 if (i != m_steps.length - 1) 45 { 46 if (m_stepindex == i + 1) 47 { 48 g.drawline(new pen(m_stepforecolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth) - intsplitwidth / 2, y + (m_stepwidth / 2))); 49 g.drawline(new pen(m_stepbackcolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth + intsplitwidth / 2, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth), y + (m_stepwidth / 2))); 50 } 51 else 52 { 53 g.drawline(new pen(m_stepforecolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth), y + (m_stepwidth / 2))); 54 } 55 } 56 } 57 else 58 { 59 if (i != m_steps.length - 1) 60 { 61 g.drawline(new pen(m_stepbackcolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth), y + (m_stepwidth / 2))); 62 } 63 } 64 65 system.drawing.sizef _numsize = g.measurestring((i + 1).tostring(), this.font); 66 g.drawstring((i + 1).tostring(), font, new solidbrush(m_stepfontcolor), new point(intleft + i * (m_stepwidth + intsplitwidth) + (m_stepwidth - (int)_numsize.width) / 2 + 1, y + (m_stepwidth - (int)_numsize.height) / 2 + 1)); 67 #endregion 68 69 system.drawing.sizef sizetxt = g.measurestring(m_steps[i], this.font); 70 g.drawstring(m_steps[i], font, new solidbrush(m_stepindex > i ? m_stepforecolor : m_stepbackcolor), new point(intleft + i * (m_stepwidth + intsplitwidth) + (m_stepwidth - (int)sizetxt.width) / 2 + 1, inttxty)); 71 } 72 } 73 74 }
全部代码
1 using system; 2 using system.collections.generic; 3 using system.componentmodel; 4 using system.drawing; 5 using system.data; 6 using system.linq; 7 using system.text; 8 using system.windows.forms; 9 using system.drawing.drawing2d; 10 11 namespace hzh_controls.controls 12 { 13 public partial class ucstep : usercontrol 14 { 15 16 [description("步骤更改事件"), category("自定义")] 17 public event eventhandler indexchecked; 18 19 private color m_stepbackcolor = color.fromargb(100, 100, 100); 20 /// <summary> 21 /// 步骤背景色 22 /// </summary> 23 [description("步骤背景色"), category("自定义")] 24 public color stepbackcolor 25 { 26 get { return m_stepbackcolor; } 27 set { m_stepbackcolor = value; } 28 } 29 30 private color m_stepforecolor = color.fromargb(255, 85, 51); 31 /// <summary> 32 /// 步骤前景色 33 /// </summary> 34 [description("步骤前景色"), category("自定义")] 35 public color stepforecolor 36 { 37 get { return m_stepforecolor; } 38 set { m_stepforecolor = value; } 39 } 40 41 private color m_stepfontcolor = color.white; 42 /// <summary> 43 /// 步骤文字颜色 44 /// </summary> 45 [description("步骤文字景色"), category("自定义")] 46 public color stepfontcolor 47 { 48 get { return m_stepfontcolor; } 49 set { m_stepfontcolor = value; } 50 } 51 52 private int m_stepwidth = 35; 53 /// <summary> 54 /// 步骤宽度 55 /// </summary> 56 [description("步骤宽度景色"), category("自定义")] 57 public int stepwidth 58 { 59 get { return m_stepwidth; } 60 set { m_stepwidth = value; } 61 } 62 63 private string[] m_steps = new string[] { "step1", "step2", "step3" }; 64 65 [description("步骤"), category("自定义")] 66 public string[] steps 67 { 68 get { return m_steps; } 69 set 70 { 71 if (m_steps == null || m_steps.length <= 1) 72 return; 73 m_steps = value; 74 refresh(); 75 } 76 } 77 78 private int m_stepindex = 0; 79 80 [description("步骤位置"), category("自定义")] 81 public int stepindex 82 { 83 get { return m_stepindex; } 84 set 85 { 86 if (m_stepindex >= steps.length) 87 return; 88 m_stepindex = value; 89 refresh(); 90 if (indexchecked != null) 91 { 92 indexchecked(this, null); 93 } 94 } 95 } 96 97 public ucstep() 98 { 99 initializecomponent(); 100 this.setstyle(controlstyles.allpaintinginwmpaint, true); 101 this.setstyle(controlstyles.doublebuffer, true); 102 this.setstyle(controlstyles.resizeredraw, true); 103 this.setstyle(controlstyles.selectable, true); 104 this.setstyle(controlstyles.supportstransparentbackcolor, true); 105 this.setstyle(controlstyles.userpaint, true); 106 } 107 108 protected override void onpaint(painteventargs e) 109 { 110 base.onpaint(e); 111 var g = e.graphics; 112 g.smoothingmode = smoothingmode.antialias; //使绘图质量最高,即消除锯齿 113 g.interpolationmode = interpolationmode.highqualitybicubic; 114 g.compositingquality = compositingquality.highquality; 115 116 if (m_steps != null && m_steps.length > 0) 117 { 118 system.drawing.sizef sizefirst = g.measurestring(m_steps[0], this.font); 119 int y = (this.height - m_stepwidth - 10 - (int)sizefirst.height) / 2; 120 if (y < 0) 121 y = 0; 122 123 int inttxty = y + m_stepwidth + 10; 124 int intleft = 0; 125 if (sizefirst.width > m_stepwidth) 126 { 127 intleft = (int)(sizefirst.width - m_stepwidth) / 2 + 1; 128 } 129 130 int intright = 0; 131 system.drawing.sizef sizeend = g.measurestring(m_steps[m_steps.length - 1], this.font); 132 if (sizeend.width > m_stepwidth) 133 { 134 intright = (int)(sizeend.width - m_stepwidth) / 2 + 1; 135 } 136 137 int intsplitwidth = 20; 138 intsplitwidth = (this.width - m_steps.length - (m_steps.length * m_stepwidth) - intright) / (m_steps.length - 1); 139 if (intsplitwidth < 20) 140 intsplitwidth = 20; 141 142 for (int i = 0; i < m_steps.length; i++) 143 { 144 #region 画圆,横线 145 g.fillellipse(new solidbrush(m_stepbackcolor), new rectangle(new point(intleft + i * (m_stepwidth + intsplitwidth), y), new size(m_stepwidth, m_stepwidth))); 146 147 if (m_stepindex > i) 148 { 149 g.fillellipse(new solidbrush(m_stepforecolor), new rectangle(new point(intleft + i * (m_stepwidth + intsplitwidth) + 2, y + 2), new size(m_stepwidth - 4, m_stepwidth - 4))); 150 151 if (i != m_steps.length - 1) 152 { 153 if (m_stepindex == i + 1) 154 { 155 g.drawline(new pen(m_stepforecolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth) - intsplitwidth / 2, y + (m_stepwidth / 2))); 156 g.drawline(new pen(m_stepbackcolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth + intsplitwidth / 2, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth), y + (m_stepwidth / 2))); 157 } 158 else 159 { 160 g.drawline(new pen(m_stepforecolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth), y + (m_stepwidth / 2))); 161 } 162 } 163 } 164 else 165 { 166 if (i != m_steps.length - 1) 167 { 168 g.drawline(new pen(m_stepbackcolor, 2), new point(intleft + i * (m_stepwidth + intsplitwidth) + m_stepwidth, y + (m_stepwidth / 2)), new point((i + 1) * (m_stepwidth + intsplitwidth), y + (m_stepwidth / 2))); 169 } 170 } 171 172 system.drawing.sizef _numsize = g.measurestring((i + 1).tostring(), this.font); 173 g.drawstring((i + 1).tostring(), font, new solidbrush(m_stepfontcolor), new point(intleft + i * (m_stepwidth + intsplitwidth) + (m_stepwidth - (int)_numsize.width) / 2 + 1, y + (m_stepwidth - (int)_numsize.height) / 2 + 1)); 174 #endregion 175 176 system.drawing.sizef sizetxt = g.measurestring(m_steps[i], this.font); 177 g.drawstring(m_steps[i], font, new solidbrush(m_stepindex > i ? m_stepforecolor : m_stepbackcolor), new point(intleft + i * (m_stepwidth + intsplitwidth) + (m_stepwidth - (int)sizetxt.width) / 2 + 1, inttxty)); 178 } 179 } 180 181 } 182 } 183 }
1 namespace hzh_controls.controls 2 { 3 partial class ucstep 4 { 5 /// <summary> 6 /// 必需的设计器变量。 7 /// </summary> 8 private system.componentmodel.icontainer components = null; 9 10 /// <summary> 11 /// 清理所有正在使用的资源。 12 /// </summary> 13 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> 14 protected override void dispose(bool disposing) 15 { 16 if (disposing && (components != null)) 17 { 18 components.dispose(); 19 } 20 base.dispose(disposing); 21 } 22 23 #region 组件设计器生成的代码 24 25 /// <summary> 26 /// 设计器支持所需的方法 - 不要 27 /// 使用代码编辑器修改此方法的内容。 28 /// </summary> 29 private void initializecomponent() 30 { 31 this.suspendlayout(); 32 // 33 // ucstep 34 // 35 this.autoscalemode = system.windows.forms.autoscalemode.none; 36 this.backcolor = system.drawing.color.transparent; 37 this.name = "ucstep"; 38 this.size = new system.drawing.size(239, 80); 39 this.resumelayout(false); 40 41 } 42 43 #endregion 44 } 45 }
用处及效果
最后的话
如果你喜欢的话,请到 点个星 星吧