鸣谢

随着前面几个章节对控件封装与扩展的分享,不少小伙伴儿们在作者公众号上反馈,并联系作者,表示通过这些系列和源码能学到不少细节上的东西,并运用到了自己的实际项目当中,也有不少伙伴儿反馈更好更优的处理方式。作者在此感谢大家的陪伴与探讨,希望能与大家一起学习,一起进步。

工欲善其事必先利其器

公众号反馈最多的是《玩转控件:封装Dev的LabelControl和TextEdit》,表示运用到自己实际项目后,确实大大减少了自己的工作量,并希望能有更多这种类型的博文。为了满足小伙伴儿的心愿,作者后续会分享更多自己实际项目运用到的小技巧,希望能对更多小伙伴儿有更多的帮助和启发。最后,也希望小伙伴儿们能从作者分享对不同类型控件的封装中举一反三,扩展满足自己实际业务的插件。有好的想法,别忘记分享给作者哦,三人行,必有我师嘛~

Talk is Cheap

废话不多说,今天作者要分享的也是作者实际项目中遇到的问题——有数据源的下拉搜索框。不少大的企业反馈,公司职员比较多,数据量比较大,鼠标下拉寻找太过繁琐和耗时,能不能提供个更优的处理方式。经过作者一番思索,以迅雷不及掩耳盗铃响叮当之势就找到了符合客户的处理方式——就是Dev的SearchLookupEdit。

大家也可以直接用Dev的SearchLookupEdit控件,效果还不错,当然为了方便起见,减少自己的操作量,也可以模仿《玩转控件:封装Dev的LabelControl和TextEdit》一样,自己根据实际情况做个封装,来吧!作者陪大家一起重温下封装的乐趣。

Show me the Code

  和往常一样,新建一个类用来封装和扩展自己实际要用到的属性和事件:

  1. public partial class KzxSearchComboboxEdit : KzxBaseControl

初始化的时候,就可以封装好自己要用到的事件:

  1. public KzxSearchComboboxEdit()
  2. {
  3. InitializeComponent();
  4.  
  5. this.ValueControl.QueryPopUp += new CancelEventHandler(lookUpEdit_QueryPopUp);
  6. this.ValueControl.Closed += new ClosedEventHandler(lookUpEdit_Closed);
  7.  
  8. this.CaptionControl.AutoSizeMode = LabelAutoSizeMode.Vertical;
  9. this.CaptionControl.SizeChanged += new EventHandler(SetSize);
  10. this.ValueControl.Enter -= new EventHandler(ValueControl_Enter);
  11. this.ValueControl.Enter += new EventHandler(ValueControl_Enter);
  12.  
  13. this._SearchLookUpEditView.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
  14. this._SearchLookUpEditView.Name = "gridLookUpEdit1View";
  15. this._SearchLookUpEditView.OptionsSelection.EnableAppearanceFocusedCell = false;
  16. this._SearchLookUpEditView.OptionsView.ShowGroupPanel = false;
  17. this.ValueControl.Properties.PopupFormSize = new System.Drawing.Size((int)(this.ValueControl.Width * ), (int)(this.ValueControl.Width * 1.5));
  18.  
  19. if (this.DesignMode == true)
  20. {
  21. this.Size = new Size(, );
  22. }
  23. }

把自己实际需要用到的属性做好封装,举个栗子:

  1. private int _ItemIndex = -;
  2. /// <summary>
  3. /// 选中项的下标
  4. /// </summary>
  5. [Category("自定义"), Description("ItemIndex,选中项的下标"), Browsable(false)]
  6. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  7. [McDisplayName("ItemIndex")]
  8. public int ItemIndex
  9. {
  10. get
  11. {
  12. return this._ItemIndex;
  13. }
  14. protected set
  15. {
  16. this._ItemIndex = value;
  17. }
  18. }
  19.  
  20. private DataRow _CurrentItem = null;
  21. /// <summary>
  22. /// 选中项的DataRow对象
  23. /// </summary>
  24. [Category("自定义"), Description("CurrentItem,选中项的DataRow对象"), Browsable(false)]
  25. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  26. [McDisplayName("CurrentItem")]
  27. public DataRow CurrentItem
  28. {
  29. get
  30. {
  31. return this._CurrentItem;
  32. }
  33. protected set
  34. {
  35. this._CurrentItem = value;
  36. }
  37. }
  38.  
  39. private DataSet _BillDataSet = new DataSet();
  40. /// <summary>
  41. /// 单据的数据源
  42. /// </summary>
  43. [Category("自定义"), Description("BillDataSet,单据的数据源"), Browsable(false)]
  44. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  45. [McDisplayName("BillDataSet")]
  46. public DataSet BillDataSet
  47. {
  48. get
  49. {
  50. return this._BillDataSet;
  51. }
  52. set
  53. {
  54. this._BillDataSet = value;
  55. }
  56. }
  57.  
  58. /// <summary>
  59. /// 没有多语言的情况下的默认显示标题
  60. /// </summary>
  61. [Category("多语言"), Description("DesigeCaption,没有多语言的情况下的默认显示标题"), Browsable(true)]
  62. [McDisplayName("DesigeCaption")]
  63. public override string DesigeCaption
  64. {
  65. get
  66. {
  67. return this.CaptionControl.Text.Trim();
  68. }
  69. set
  70. {
  71. this.CaptionControl.Text = value;
  72. }
  73. }

也可以根据自己喜好(当然是符合客户习惯的),画蛇添足:

  1. private bool _IsNull = true;
  2. /// <summary>
  3. /// 可空性
  4. /// </summary>
  5. [Category("验证"), Description("IsNull,可空性"), Browsable(true)]
  6. [McDisplayName("IsNull")]
  7. public override bool IsNull
  8. {
  9. get
  10. {
  11. SetBackColor();
  12. return this._IsNull;
  13. }
  14. set
  15. {
  16. this._IsNull = value;
  17. SetBackColor();
  18. }
  19. }
  20. ...
  21. /// <summary>
  22. /// 设置背景色
  23. /// </summary>
  24. private void SetBackColor()
  25. {
  26. if (this.ValueControl.Properties.ReadOnly == true)
  27. {
  28. this.ValueControl.BackColor = Color.FromArgb(, , );
  29. }
  30. else
  31. {
  32. if (this._IsNull.Equals(true) == false)
  33. {
  34. this.ValueControl.BackColor = Color.Yellow;
  35. }
  36. else
  37. {
  38. this.ValueControl.BackColor = this._TextBackColor;
  39. }
  40. }
  41. }

当设置控件必填的时候,设置控件的背景色用于区分,具体效果如图:

封装好控件取值,填充值的方法,以及控件数据源绑定的方法(具体根据自己实际项目应用为准,此处只是举个栗子)

  1. /// <summary>
  2. /// 取控件的值
  3. /// </summary>
  4. /// <return>Object</return>
  5. public override object GetValue()
  6. {
  7. DataRowView rowview = null;
  8. BindingSource bs = null;
  9. object v = null;
  10.  
  11. v = this.ValueControl.EditValue == null || this.ValueControl.EditValue == DBNull.Value ? string.Empty : this.ValueControl.EditValue.ToString();
  12. return v;
  13. }
  14.  
  15. /// <summary>
  16. /// 设置控件的值
  17. /// </summary>
  18. /// <param name="value">控件的值</param>
  19. /// <return>int</return>
  20. public override int SetValue(object value)
  21. {
  22. this.ValueControl.EditValue = value == null || value == DBNull.Value ? string.Empty : value;
  23. return ;
  24. }
  25.  
  26. /// <summary>
  27. /// 设置数据绑定
  28. /// </summary>
  29. /// <param name="binding">数据绑定对象</param>
  30. /// <return>int</return>
  31. public override int SetDataBinding(object binding)
  32. {
  33. this.BindingObject = this.ValueControl.DataBindings.Add("EditValue", binding, this.Field, true, DataSourceUpdateMode.OnValidation, string.Empty, this.FormatString);
  34. SetColumnDisplayFormat();
  35. if (binding is BindingSource)
  36. {
  37. int maxlength = ;
  38. if (((BindingSource)binding).DataSource is DataView)
  39. {
  40. if (((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].DataType == typeof(string))
  41. {
  42. maxlength = ((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].MaxLength;
  43. if (maxlength >= )
  44. {
  45. this.MaxLength = maxlength;
  46. }
  47. }
  48. }
  49. else if (((BindingSource)binding).DataSource is DataTable)
  50. {
  51. if (((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].DataType == typeof(string))
  52. {
  53. maxlength = ((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].MaxLength;
  54. if (maxlength >= )
  55. {
  56. this.MaxLength = maxlength;
  57. }
  58. }
  59. }
  60. }
  61. return ;
  62. }
  63.  
  64. /// <summary>
  65. /// 设置下拉框的数据源
  66. /// </summary>
  67. /// <param name="binding">下拉框的数据源</param>
  68. /// <param name="displayMember">显示值字段名</param>
  69. /// <param name="valueMember">实际值字段名</param>
  70. /// <returns>int</returns>
  71. public override int SetSourceTableBinding(object binding, string displayMember, string valueMember)
  72. {
  73. this.DisplayMemberPath = displayMember;
  74. this.SelectedValuePath = valueMember;
  75. this.ValueControl.Properties.DataSource = binding;
  76. this._ResourceDataSource = binding;
  77. return ;
  78. }

完成!为测试效果,在窗体Load事件中造个测试数据,看看效果:

  1. DataTable dataTable = new DataTable("Student");
  2. dataTable.Columns.Add("编号", typeof(String));
  3. dataTable.Columns.Add("昵称", typeof(String));
  4. dataTable.Columns.Add("名称", typeof(String));
  5. dataTable.Rows.Add(new String[] { "", "James", "张三" });
  6. dataTable.Rows.Add(new String[] { "", "Mary", "李四" });
  7. dataTable.Rows.Add(new String[] { "", "Jack", "王五" });
  8. dataTable.Rows.Add(new String[] { "", "joy", "赵六" });
  9. dataTable.Rows.Add(new String[] { "", "jay", "钱七"});
  10. dataTable.Rows.Add(new String[] { "", "stephen", "康忠鑫"});
  11.  
  12. kzxSearchCbbeSupperStar.SetSourceTableBinding(dataTable, "名称", "昵称");

和原始Dev控件一样,支持筛选功能,妈妈再也不用担心客户反馈因数据量大的问题查找不便了!

结束语

由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号联系博主,源码可以免费赠予~!有疑问的也可以CALL我一起探讨。

最后,感谢您的耐心陪伴!如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!

玩转控件:封装Dev的SearchLookupEdit的更多相关文章

  1. 玩转控件:封装Dev的LabelControl和TextEdit

    俗话说的好:"工欲善其事必先利其器",作为软件攻城狮也是同样道理,攻城狮开发的软件目的是简化客户的操作,让客户动动手指就可以完成很多事情,减少人力成本.这也是系统/软件存在的目的. ...

  2. 玩转控件:对Dev的GridControl控件扩展

    缘由 一切实现来源于需求,目的在于不盲目造轮子,有小伙伴儿在看了<玩转控件:对Dev中GridControl控件的封装和扩展>文章后,私信作者说,因公司业务逻辑比较复杂,展示字段比较多,尤 ...

  3. 玩转控件:扩展Dev中SimpleButton

    何为扩展,顾名思义,就是在原有控件属性.事件的基础上拓展自己需要或实用的属性.事件等等.或者可以理解为,现有的控件已经不能完全满足我(的需求)了.好的扩展会使控件更加完善,实用,好用.不好的扩展,说白 ...

  4. 玩转控件:对Dev中GridControl控件的封装和扩展

    又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动.... 转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠.裁员的裁员,降薪的降薪,996的996~~说起来都是泪,以 ...

  5. 玩转控件:Fucking ERP之流程图

    前言 首先,跟守护在作者公众号和私信作者催更的朋友们道个歉.疫情的原因,公司从年初到现在一直处于996+的高压模式,导致公众号更新频率较低.而且作者每更新一篇原创公众号,既要对自己沉淀知识负责,也要对 ...

  6. 玩转控件:重写/重绘Dev中MessageBox弹窗控件

    很久没有更新博客了,本想着直接发一篇<手撕ERP>系列,从控件重写.重绘,到框架搭建,再到部分模块实现+业务的.但是每次动手的时候,都觉得难以下手.直接从数据库设计开始吧,模块设计还没定下 ...

  7. 玩转控件:重绘DEVEXPRESS中DateEdit控件 —— 让DateEdit支持只选择年月 (提供源码下载)

      前言 上一篇博文<玩转控件:重绘ComboBox —— 让ComboBox多列显示>中,根据大家的回馈,ComboBox已经支持筛选了,更新见博文最后最后最后面.   奇葩 这两天遇到 ...

  8. 控件使用经验-MVP模式+控件封装

    项目背景 几年前参与了一个面向学校的人事管理软件的开发,基于WinForm平台.今天主要想谈一谈其中关于控件的使用经验.这个项目我们大量使用了第三方控件.由于这个产品的生命周期很长,我们在设计时要考虑 ...

  9. 尝试使用UISearchDisplayController及对苹果对控件封装习惯的理解

    本文转载至 http://blog.sina.com.cn/s/blog_74e9d98d01019vji.html   在之前做过的应用中,很多都有“搜索”这个功能,大部分情况下我都是只采用UISe ...

随机推荐

  1. Windows安装python包出现PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问的问题解决方案

    在python中安装sqlalchemy时,总是提示(当安装依赖有vs的python包时,可能会出现以下错误:) PermissionError: [WinError 32] 另一个程序正在使用此文件 ...

  2. pycharm专业版激活破解(亲测有效)

    完成破解步骤,亲测有效! 1.打开路径,修改hosts文件:C:\Windows\System32\drivers\etc 找到hosts文件打开 最后一行添加这行代码:   0.0.0.0 acco ...

  3. Gnome 究极无死角美化!!!不要再说gnome丑啦!!!

    一.本文针对的美化部分包括:主题.图标.锁屏.开关机画面.gurb.插件.鼠标.终端及其配色方案. 二.资源下载: 1.请先下载好资源再继续进行.下列两个网址的内容一样,请根据下载体验自行选择. 超星 ...

  4. Simulink仿真入门到精通(十) S函数

    10.1 S函数概述 S函数也称为Simulink中的系统函数,是用来描述模块的Simulink宏函数,支持M.C等多种语言.当Simulink默认的模块不能满足用户的需求时,用户可以通过S函数自己打 ...

  5. c js 字符串反转

    1.例如:输入 i am     a student    输出 student a am i #include <stdio.h> #include <string.h> v ...

  6. sklearn-转换器与机器学习流程

    一.sklearn估计器 二.机器学习开发流程 .

  7. 如何在vue中修改动态标签中的样式和修改组件库样式

    vue中修改动态标签中的样式和修改组件库样式 因为vue中的标签在渲染的时候,都会给标签加上id 所以你想在<style lang="scss" scoped>直接修改 ...

  8. 爬虫 | Python下载m3u8视频

    目录 从 m3u8 文件中解析出 ts 信息 按时间截取视频 抓取 ts 文件 单文件测试 批量下载 合并 ts 文件 将合并的ts文件转化为视频文件 参考资料: m3u8格式介绍 ts文件格式介绍 ...

  9. Blazor-断开连接后重新加载浏览器

    在大多数情况下,Blazor将与以前相同的线路上重新连接到服务器.但有时无法重新连接,需要重新加载web浏览器才能使网站重新工作.如果服务器回收应用程序池,则需要手动重新加载页面在没有调试的情况下在I ...

  10. hdu2544SPFA板题

    SPFA顾名思义就是更快的最短路算法,是Bellman ford算法的优化,SPFA的平均复杂度大约是O(K*|E|),在一般情况下K大约是小于等于2的数,但是总有人对你心怀不轨,构造一组SPFA最坏 ...