C#中Winform 实现Ajax效果自定义按钮
程序员文章站
2023-12-17 12:26:28
技术看点
winform自定义控件的使用
自定义控件gif动画的播放
需求及效果
又来一波 c# gdi自定义控件show 。这个控件已...
技术看点
- winform自定义控件的使用
- 自定义控件gif动画的播放
需求及效果
又来一波 c# gdi自定义控件show 。这个控件已经使用几年了,最近找出来重构一下。原来是没有边框的,那么导致导航的功能不是很突出。本来想加个效果:在执行单击时显示loading动画,在执行完单击事件后恢复原样。这就是网页里见到的局部刷新,ajax常用的场景。需求来自几年前一个智能储物柜项目,人机界面有个美工设计好的效果图,为了省事和通用,需要一个透明的按钮来实现导航的任务。就是控件只是设计时可见,运行时不可见。
关键点说明
1)、graphicspath实现矩形的圆角羽化处理
using (graphicspath path = new graphicspath()) { #region 羽化,圆角处理 path.startfigure(); path.addarc(new rectangle(new point(rect.x, rect.y), new size(2 * radius, 2 * radius)), 180, 90); path.addline(new point(rect.x + radius, rect.y), new point(rect.right - radius, rect.y)); path.addarc(new rectangle(new point(rect.right - 2 * radius, rect.y), new size(2 * radius, 2 * radius)), 270, 90); path.addline(new point(rect.right, rect.y + radius), new point(rect.right, rect.bottom - radius)); path.addarc(new rectangle(new point(rect.right - 2 * radius, rect.bottom - 2 * radius), new size(2 * radius, 2 * radius)), 0, 90); path.addline(new point(rect.right - radius, rect.bottom), new point(rect.x + radius, rect.bottom)); path.addarc(new rectangle(new point(rect.x, rect.bottom - 2 * radius), new size(2 * radius, 2 * radius)), 90, 90); path.addline(new point(rect.x, rect.bottom - radius), new point(rect.x, rect.y + radius)); path.closefigure(); #endregion
要点就是画几段弧线和矩形连接起来。透明就是用了color.fromargb加上透明度,然后填充graphicspath形成透明区域。
g.fillpath(new solidbrush(color.fromargb(153, backcolor)), path);
2)、单窗体应用如何模块化
窗体只有一个,但操作界面好多个,由于是无人值守的应用。那么老是切换窗体操作是非常不方便的。工作区域是一个容器panel,把每个操作界面定义成一个panel作为只容器。
public partial class depositbizpanel : usercontrol { private backgroundstyle backgroundstyle = backgroundstyle.green; /// <summary> /// 主题风格 /// </summary> public backgroundstyle backgroundstyle { get { return backgroundstyle; } set { backgroundstyle = value; switch (value) { case greenlandexpressbox.backgroundstyle.blue: backgroundimage = properties.resources.jbblue; break; case greenlandexpressbox.backgroundstyle.orange: backgroundimage = properties.resources.jborange; break; case greenlandexpressbox.backgroundstyle.green: backgroundimage = properties.resources.jbgreen; break; } invalidate(); } } public panel parentpanel { get; set; } public bitmap qr_barcode { get { return (bitmap)pbxbarcode.image; } set { pbxbarcode.image = value; } } public dialogresult paneldiagresult { get; set; } public depositbizpanel(panel parent, bitmap barcode, backgroundstyle style) { initializecomponent(); doublebuffered = true; parentpanel = parent; qr_barcode = barcode; backgroundstyle = style; } private void btnback_click(object sender, eventargs e) { foreach (control panel in parentpanel.controls) { if (panel is depositbizpanel) { parentpanel.controls.remove(panel); paneldiagresult = dialogresult.cancel; break; } } } private void btnprocessnext_click(object sender, eventargs e) { foreach (control panel in parentpanel.controls) { if (panel is depositbizpanel) { parentpanel.controls.remove(panel); paneldiagresult = dialogresult.ok; break; } } } }
人机操作界面例子
3)、控件播放gif动画
private void beginanimate() { if (m_animateimage == null) return; if (imageanimator.cananimate(m_animateimage)) { //当gif动画每隔一定时间后,都会变换一帧,那么就会触发一事件, //该方法就是将当前image每变换一帧时,都会调用当前这个委托所关联的方法。 imageanimator.animate(m_animateimage, m_evthdlanimator); } } private void stopanimate() { if (m_animateimage == null) return; try { if (imageanimator.cananimate(m_animateimage)) { imageanimator.stopanimate(m_animateimage, m_evthdlanimator); } } finally { m_isexecuted = false; } } private void updateimage() { if (m_animateimage == null) return; if (imageanimator.cananimate(m_animateimage)) { //获得当前gif动画的下一步需要渲染的帧,当下一步任何对当前gif动画的操作都是对该帧进行操作) imageanimator.updateframes(m_animateimage); } } private void onimageanimate(object sender, eventargs e) { invalidate(); } protected override void onload(eventargs e) { base.onload(e); string s1 = @"r0lgodlhiaagalmaap///7ozs/v7+9bw1uhh4fly8rq6uogbgtq0naebarsbg8texjexl/39/vruvaaaach/c05fvfndqvbfmi4waweaaaah+qqfbqaaacwaaaaaiaagaaae5xdissllrornp0pknrcdfhxvoljlejquosgopsyt4rownssvyw1ica16k8mmmrkcbjskbtfdazyuaekqcfxiq2hgqrfvaqeeijnxvdw6xne4yagrjubcwe60smqudnd4rz1zaqznfagdd0hihh12cee9kjaevlycxig7basmb6slnj87paqbskikoqusnbmdmdc2txqlkuhziytywtxify6be8wjt5yevpjivxnagmlht0vnoggyf0dzxs7apdpb309rnhog5gdqxgldac457d1zz/v/nmom82xihqjykhkp1ozmaddeaaah+qqfbqaaacwaaaaagaaxaaaechdisaskneujfkohs4muyljikmjiv54soypsa0wmlsnqotetbw52mg0ajhypbxioeqrny8v0qfznw+ggwljki4lbqx1ibgjmkrighwjrzcdti2/gh7d9qn774wqgayoefwcchiv/gymdho+qkzktr3p7eqah+qqfbqaaacwbaaaahqaoaaaechdiswdanesnhhjzwe2duseo5sjkkb2hokgyfld1cb/dneoilkti2plyukgeatmbaaacsygbedyd4zn1yiemh0scqqgyehnmtnnaksqjxmbuueypi9ecau/ufnnzeup9vbqebofolmfxwhnoqw6rweoceqah+qqfbqaaacwhaaaagqaraaaeardicdzznovndsvfbhbddpwzgohbge3nqaki0ayejeqogmqdlkenazbujhra0cobyhlvskm4saaawkahcfawtu0a4rxzfwjnzxfwjjwb9ptihru5dvghl+/7nqmbggo/fykhcx8aiameeqah+qqfbqaaacwoaaaaegayaaaezxcwaaq9odamdouai17mcydhwa3mcypb1rooxbktmsbt944bu6zcqcbqiwpb4jaihick86irtb20qvwp7xq/fyv4tnwnz4oqwoeigl0hx/eqsli69bociktke2vvdap5d1p0cw4rach5baufaaaala4aaaasab4aaasakbgcqr3ybimxvkeimsxxhcffpizqbatxisbclibgand+ijygq2i4haamwxbgnhj8bebzgpnnjz7lwpnfdlvglgjmdnw/5drcrhae3xbkm6fqwot1xdnpwcvcjgcjmgeiecyocqlrf4ymbiojvv2ccxzvcoohbwgrcaikcmfujheaifkebquaaaasdwababeahwaabhsqyakgorivelinnoflbjem1bcifbdcbmutkqdtn0cujru5njqrymh5vifttkjcoj2hqjqrheqvqguu+uw6awgewxkoo55lxiihodjky8pbothpxmpayi+hkzoeewktdhkzghmidcoihiuhfbmojxinlr4kcw1odalxsxeaifkebquaaaascaaoabgaegaabgwqyekrcdgbyvvmoof5ilanaiogkroch9hacd3mfmhubzmhibtgwjmbfoldb4goggbcackrcaauwamzowjqexysqsjgwj0kqvkaltiyphp1lbfttp10is6mt5gdvfx1brn8ftsvcaqdob9+kheaifkebquaaaasagasab0adgaabhgqyemrbeps4bqdqzbdr5ichmwegufqgwkakbwwwsihc4lonsxhbscsqoosscgqdjiwwohqnaxwbiyjnxeofciewdi9jczesey7gwmm5doeww4jjoypqq743u1wctv0cgfzbhj5xclfhyd/ewznhoyvdgiofhkqnreaifkebquaaaasaaapabkaeqaabgeqquqrudjrw3vaycz5x2ie6ekckaootasi7ytntq046bbsnctvitz4aotmwkzbic6h6cvajacct0cubtgatg5ntcu9gkidempjg5ybbopwlnvzlwtqyknzagzwahomb2m3ggshsrsrach5baufaaaalaeacaarabgaaarcmkr0gl34npkuyycacamyhbijkgi2uw02vhft33iu7yididad4/ereygdlu/nubaoj9dvc2ecdgfayiuaxs3bboh6mic5iap5eh5fk2exc4tpgwzyiyfgvhembbeaifkebquaaaasaaacaa4ahqaabhmqyanyovislfdgxbj808ep5krwv8qeg+prcoeoiokmwjk0ekcu54h9aoghkgximzgaapqzcccu2ax2o6nuud2pmjcyha4l0udm/ljydcngfgakjqe5yh0wubybauyfbifkhwabgxkdgx5lgxphaxcpbisrads="; byte[] buffer = convert.frombase64string(s1); memorystream ms = new memorystream(buffer); var srcimg = image.fromstream(ms); m_animateimage = srcimg; }
onload执行的操作是从base64字符串里反序列化图片,就是效果图中的loading的gif图片。这里遇到一个问题:在关闭了memorystream之后,会出现“gdi+ 中发生一般性错误”,于是改为不关闭了,控件销毁之后占用的内存就会释放吧。这是一点隐忧,如果有好的办法,希望留言告知。
透明按钮自定义控件全部代码
第一版自定义按钮:
/// <summary> /// cool透明自定义按钮 /// </summary> public partial class cooltransparentbutton : usercontrol { private size iconsize = new size(32, 32); public size iconsize { get { return iconsize; } set { iconsize = value; invalidate(); } } private string _buttontext; public string buttontext { get { return _buttontext; } set { _buttontext = value; invalidate(); } } protected image _iconimage; public image iconimage { get { return _iconimage; } set { _iconimage = value; invalidate(); } } private bool _focseactived = false; private color _bordercolor = color.white; public color bordercolor { get { return _bordercolor; } set { _bordercolor = value; invalidate(); } } private int _radius = 12; public int radius { get { return _radius; } set { _radius = value; invalidate(); } } private bool ifdrawborderwhenlostfocse = true; /// <summary> /// 失去焦点是否画边框 /// </summary> public bool ifdrawborderwhenlostfocse { get { return ifdrawborderwhenlostfocse; } set { ifdrawborderwhenlostfocse = value; invalidate(); } } /// <summary> /// 是否处于激活状态(焦点) /// </summary> public bool focseactived { get { return _focseactived; } set { _focseactived = value; invalidate(); } } public cooltransparentbutton() { doublebuffered = true; backcolor = color.transparent; setstyle(controlstyles.allpaintinginwmpaint | controlstyles.optimizeddoublebuffer | controlstyles.resizeredraw, true); setstyle(controlstyles.opaque, false); updatestyles(); } protected override void onpaint(painteventargs e) { var rect = clientrectangle; rect.inflate(-1, -1); graphics g = e.graphics; g.smoothingmode = smoothingmode.highquality; using (graphicspath path = new graphicspath()) { #region 羽化,圆角处理 path.startfigure(); path.addarc(new rectangle(new point(rect.x, rect.y), new size(2 * radius, 2 * radius)), 180, 90); path.addline(new point(rect.x + radius, rect.y), new point(rect.right - radius, rect.y)); path.addarc(new rectangle(new point(rect.right - 2 * radius, rect.y), new size(2 * radius, 2 * radius)), 270, 90); path.addline(new point(rect.right, rect.y + radius), new point(rect.right, rect.bottom - radius)); path.addarc(new rectangle(new point(rect.right - 2 * radius, rect.bottom - 2 * radius), new size(2 * radius, 2 * radius)), 0, 90); path.addline(new point(rect.right - radius, rect.bottom), new point(rect.x + radius, rect.bottom)); path.addarc(new rectangle(new point(rect.x, rect.bottom - 2 * radius), new size(2 * radius, 2 * radius)), 90, 90); path.addline(new point(rect.x, rect.bottom - radius), new point(rect.x, rect.y + radius)); path.closefigure(); #endregion if (!focseactived) { if (ifdrawborderwhenlostfocse) g.drawpath(new pen(color.gray, 1), path); g.fillpath(new solidbrush(color.fromargb(66, backcolor)), path); } else { g.drawpath(new pen(bordercolor, 1), path); rect.inflate(-1, -1); g.fillpath(new solidbrush(color.fromargb(153, backcolor)), path); } #region 画文本 g.smoothingmode = smoothingmode.antialias; if (iconimage != null) { rectangle rc = new rectangle((width - 32) / 2, 16, iconsize.width, iconsize.height); g.drawimage(iconimage, rc); } if (!string.isnullorempty(buttontext)) { using (stringformat f = new stringformat()) { rectangle recttxt = new rectangle(0, (height - 18) / 2, width, 36); f.alignment = stringalignment.center;// 水平居中对齐 f.linealignment = stringalignment.center; // 垂直居中对齐 f.formatflags = stringformatflags.nowrap;// 设置为单行文本 solidbrush fb = new solidbrush(this.forecolor); // 绘制文本 e.graphics.drawstring(buttontext, new font("微软雅黑", 16f, fontstyle.bold), fb, recttxt, f); } } #endregion } } protected override void onmousehover(eventargs e) { focseactived = true; } protected override void onmouseleave(eventargs e) { focseactived = false; } protected override void onenter(eventargs e) { focseactived = true; } protected override void onleave(eventargs e) { focseactived = false; } }
第二版自定义按钮:
/// <summary> /// 自定义透明自定义按钮,模仿实现了网页元素的ajax效果 /// </summary> public partial class ajaxtransparentbutton : usercontrol { private size iconsize = new size(32, 32); public size iconsize { get { return iconsize; } set { iconsize = value; invalidate(); } } private string _buttontext; public string buttontext { get { return _buttontext; } set { _buttontext = value; invalidate(); } } protected image _iconimage; public image iconimage { get { return _iconimage; } set { _iconimage = value; invalidate(); } } private bool _focseactived = false; private color _bordercolor = color.white; public color bordercolor { get { return _bordercolor; } set { _bordercolor = value; invalidate(); } } private int _radius = 12; public int radius { get { return _radius; } set { _radius = value; invalidate(); } } private bool ifdrawborderwhenlostfocse = true; /// <summary> /// 失去焦点是否画边框 /// </summary> public bool ifdrawborderwhenlostfocse { get { return ifdrawborderwhenlostfocse; } set { ifdrawborderwhenlostfocse = value; invalidate(); } } /// <summary> /// 是否处于激活状态(焦点) /// </summary> public bool focseactived { get { return _focseactived; } set { _focseactived = value; invalidate(); } } private image m_animateimage = null; private eventhandler m_evthdlanimator = null; private bool m_isexecuted = false; public ajaxtransparentbutton() { backcolor = color.transparent; setstyle(controlstyles.allpaintinginwmpaint | controlstyles.optimizeddoublebuffer | controlstyles.resizeredraw | controlstyles.userpaint, true); setstyle(controlstyles.opaque, false); updatestyles(); m_evthdlanimator = new eventhandler(onimageanimate); } protected override void onpaint(painteventargs e) { var rect = clientrectangle; rect.inflate(-1, -1); graphics g = e.graphics; g.smoothingmode = smoothingmode.highquality; using (graphicspath path = new graphicspath()) { #region 羽化,圆角处理 path.startfigure(); path.addarc(new rectangle(new point(rect.x, rect.y), new size(2 * radius, 2 * radius)), 180, 90); path.addline(new point(rect.x + radius, rect.y), new point(rect.right - radius, rect.y)); path.addarc(new rectangle(new point(rect.right - 2 * radius, rect.y), new size(2 * radius, 2 * radius)), 270, 90); path.addline(new point(rect.right, rect.y + radius), new point(rect.right, rect.bottom - radius)); path.addarc(new rectangle(new point(rect.right - 2 * radius, rect.bottom - 2 * radius), new size(2 * radius, 2 * radius)), 0, 90); path.addline(new point(rect.right - radius, rect.bottom), new point(rect.x + radius, rect.bottom)); path.addarc(new rectangle(new point(rect.x, rect.bottom - 2 * radius), new size(2 * radius, 2 * radius)), 90, 90); path.addline(new point(rect.x, rect.bottom - radius), new point(rect.x, rect.y + radius)); path.closefigure(); #endregion if (!focseactived) { if (ifdrawborderwhenlostfocse) g.drawpath(new pen(color.gray, 1), path); g.fillpath(new solidbrush(color.fromargb(66, backcolor)), path); } else { g.drawpath(new pen(bordercolor, 1), path); rect.inflate(-1, -1); g.fillpath(new solidbrush(color.fromargb(153, backcolor)), path); } #region 画文本 g.smoothingmode = smoothingmode.antialias; if (iconimage != null) { rectangle rc = new rectangle((width - 32) / 2, 16, iconsize.width, iconsize.height); g.drawimage(iconimage, rc); } if (!string.isnullorempty(buttontext)) { using (stringformat f = new stringformat()) { rectangle recttxt = new rectangle(0, (height - 18) / 2, width, 36); f.alignment = stringalignment.center;// 水平居中对齐 f.linealignment = stringalignment.center; // 垂直居中对齐 f.formatflags = stringformatflags.nowrap;// 设置为单行文本 solidbrush fb = new solidbrush(this.forecolor); // 绘制文本 e.graphics.drawstring(buttontext, new font("微软雅黑", 16f, fontstyle.bold), fb, recttxt, f); } } if (m_animateimage != null) { rectangle rectgif = new rectangle((width - 24) / 2, (height - 16) / 2 - 8, 32, 32); if (m_isexecuted) { updateimage(); e.graphics.drawimage(m_animateimage, rectgif); } else { e.graphics.fillrectangle(new solidbrush(color.transparent), rectgif); } } #endregion } } protected override void onmousehover(eventargs e) { focseactived = true; } protected override void onmouseleave(eventargs e) { focseactived = false; } protected override void onenter(eventargs e) { focseactived = true; } protected override void onleave(eventargs e) { focseactived = false; } private void beginanimate() { if (m_animateimage == null) return; if (imageanimator.cananimate(m_animateimage)) { //当gif动画每隔一定时间后,都会变换一帧,那么就会触发一事件, //该方法就是将当前image每变换一帧时,都会调用当前这个委托所关联的方法。 imageanimator.animate(m_animateimage, m_evthdlanimator); } } private void stopanimate() { if (m_animateimage == null) return; try { if (imageanimator.cananimate(m_animateimage)) { imageanimator.stopanimate(m_animateimage, m_evthdlanimator); } } finally { m_isexecuted = false; } } private void updateimage() { if (m_animateimage == null) return; if (imageanimator.cananimate(m_animateimage)) { //获得当前gif动画的下一步需要渲染的帧,当下一步任何对当前gif动画的操作都是对该帧进行操作) imageanimator.updateframes(m_animateimage); } } private void onimageanimate(object sender, eventargs e) { invalidate(); } protected override void onload(eventargs e) { base.onload(e); string s1 = @"r0lgodlhiaagalmaap///7ozs/v7+9bw1uhh4fly8rq6uogbgtq0naebarsbg8texjexl/39/vruvaaaach/c05fvfndqvbfmi4waweaaaah+qqfbqaaacwaaaaaiaagaaae5xdissllrornp0pknrcdfhxvoljlejquosgopsyt4rownssvyw1ica16k8mmmrkcbjskbtfdazyuaekqcfxiq2hgqrfvaqeeijnxvdw6xne4yagrjubcwe60smqudnd4rz1zaqznfagdd0hihh12cee9kjaevlycxig7basmb6slnj87paqbskikoqusnbmdmdc2txqlkuhziytywtxify6be8wjt5yevpjivxnagmlht0vnoggyf0dzxs7apdpb309rnhog5gdqxgldac457d1zz/v/nmom82xihqjykhkp1ozmaddeaaah+qqfbqaaacwaaaaagaaxaaaechdisaskneujfkohs4muyljikmjiv54soypsa0wmlsnqotetbw52mg0ajhypbxioeqrny8v0qfznw+ggwljki4lbqx1ibgjmkrighwjrzcdti2/gh7d9qn774wqgayoefwcchiv/gymdho+qkzktr3p7eqah+qqfbqaaacwbaaaahqaoaaaechdiswdanesnhhjzwe2duseo5sjkkb2hokgyfld1cb/dneoilkti2plyukgeatmbaaacsygbedyd4zn1yiemh0scqqgyehnmtnnaksqjxmbuueypi9ecau/ufnnzeup9vbqebofolmfxwhnoqw6rweoceqah+qqfbqaaacwhaaaagqaraaaeardicdzznovndsvfbhbddpwzgohbge3nqaki0ayejeqogmqdlkenazbujhra0cobyhlvskm4saaawkahcfawtu0a4rxzfwjnzxfwjjwb9ptihru5dvghl+/7nqmbggo/fykhcx8aiameeqah+qqfbqaaacwoaaaaegayaaaezxcwaaq9odamdouai17mcydhwa3mcypb1rooxbktmsbt944bu6zcqcbqiwpb4jaihick86irtb20qvwp7xq/fyv4tnwnz4oqwoeigl0hx/eqsli69bociktke2vvdap5d1p0cw4rach5baufaaaala4aaaasab4aaasakbgcqr3ybimxvkeimsxxhcffpizqbatxisbclibgand+ijygq2i4haamwxbgnhj8bebzgpnnjz7lwpnfdlvglgjmdnw/5drcrhae3xbkm6fqwot1xdnpwcvcjgcjmgeiecyocqlrf4ymbiojvv2ccxzvcoohbwgrcaikcmfujheaifkebquaaaasdwababeahwaabhsqyakgorivelinnoflbjem1bcifbdcbmutkqdtn0cujru5njqrymh5vifttkjcoj2hqjqrheqvqguu+uw6awgewxkoo55lxiihodjky8pbothpxmpayi+hkzoeewktdhkzghmidcoihiuhfbmojxinlr4kcw1odalxsxeaifkebquaaaascaaoabgaegaabgwqyekrcdgbyvvmoof5ilanaiogkroch9hacd3mfmhubzmhibtgwjmbfoldb4goggbcackrcaauwamzowjqexysqsjgwj0kqvkaltiyphp1lbfttp10is6mt5gdvfx1brn8ftsvcaqdob9+kheaifkebquaaaasagasab0adgaabhgqyemrbeps4bqdqzbdr5ichmwegufqgwkakbwwwsihc4lonsxhbscsqoosscgqdjiwwohqnaxwbiyjnxeofciewdi9jczesey7gwmm5doeww4jjoypqq743u1wctv0cgfzbhj5xclfhyd/ewznhoyvdgiofhkqnreaifkebquaaaasaaapabkaeqaabgeqquqrudjrw3vaycz5x2ie6ekckaootasi7ytntq046bbsnctvitz4aotmwkzbic6h6cvajacct0cubtgatg5ntcu9gkidempjg5ybbopwlnvzlwtqyknzagzwahomb2m3ggshsrsrach5baufaaaalaeacaarabgaaarcmkr0gl34npkuyycacamyhbijkgi2uw02vhft33iu7yididad4/ereygdlu/nubaoj9dvc2ecdgfayiuaxs3bboh6mic5iap5eh5fk2exc4tpgwzyiyfgvhembbeaifkebquaaaasaaacaa4ahqaabhmqyanyovislfdgxbj808ep5krwv8qeg+prcoeoiokmwjk0ekcu54h9aoghkgximzgaapqzcccu2ax2o6nuud2pmjcyha4l0udm/ljydcngfgakjqe5yh0wubybauyfbifkhwabgxkdgx5lgxphaxcpbisrads="; byte[] buffer = convert.frombase64string(s1); memorystream ms = new memorystream(buffer); var srcimg = image.fromstream(ms); m_animateimage = srcimg; } protected override void onclick(eventargs e) { if (m_isexecuted) return; action clicktask = () => { m_isexecuted = true; beginanimate(); base.onclick(e); invalidate(); }; //异步执行单击事件 clicktask.begininvoke((result) => { clicktask.endinvoke(result); m_isexecuted = false; stopanimate(); }, null); } protected override void dispose(bool disposing) { base.dispose(disposing); if (m_animateimage != null) { try { stopanimate(); } finally { m_animateimage.dispose(); m_evthdlanimator = null; } } } protected override void onkeydown(keyeventargs e) { base.onkeydown(e); if (e.keycode == keys.enter) { onclick(e); } } }
注释不是很多,源码如有需要拿走不谢