玩转控件:封装Dev的SearchLookupEdit
鸣谢
随着前面几个章节对控件封装与扩展的分享,不少小伙伴儿们在作者公众号上反馈,并联系作者,表示通过这些系列和源码能学到不少细节上的东西,并运用到了自己的实际项目当中,也有不少伙伴儿反馈更好更优的处理方式。作者在此感谢大家的陪伴与探讨,希望能与大家一起学习,一起进步。
工欲善其事必先利其器
公众号反馈最多的是《玩转控件:封装Dev的LabelControl和TextEdit》,表示运用到自己实际项目后,确实大大减少了自己的工作量,并希望能有更多这种类型的博文。为了满足小伙伴儿的心愿,作者后续会分享更多自己实际项目运用到的小技巧,希望能对更多小伙伴儿有更多的帮助和启发。最后,也希望小伙伴儿们能从作者分享对不同类型控件的封装中举一反三,扩展满足自己实际业务的插件。有好的想法,别忘记分享给作者哦,三人行,必有我师嘛~
Talk is Cheap
废话不多说,今天作者要分享的也是作者实际项目中遇到的问题——有数据源的下拉搜索框。不少大的企业反馈,公司职员比较多,数据量比较大,鼠标下拉寻找太过繁琐和耗时,能不能提供个更优的处理方式。经过作者一番思索,以迅雷不及掩耳盗铃响叮当之势就找到了符合客户的处理方式——就是Dev的SearchLookupEdit。
大家也可以直接用Dev的SearchLookupEdit控件,效果还不错,当然为了方便起见,减少自己的操作量,也可以模仿《玩转控件:封装Dev的LabelControl和TextEdit》一样,自己根据实际情况做个封装,来吧!作者陪大家一起重温下封装的乐趣。
Show me the Code
和往常一样,新建一个类用来封装和扩展自己实际要用到的属性和事件:
public partial class KzxSearchComboboxEdit : KzxBaseControl
初始化的时候,就可以封装好自己要用到的事件:
public KzxSearchComboboxEdit()
{
InitializeComponent(); this.ValueControl.QueryPopUp += new CancelEventHandler(lookUpEdit_QueryPopUp);
this.ValueControl.Closed += new ClosedEventHandler(lookUpEdit_Closed); this.CaptionControl.AutoSizeMode = LabelAutoSizeMode.Vertical;
this.CaptionControl.SizeChanged += new EventHandler(SetSize);
this.ValueControl.Enter -= new EventHandler(ValueControl_Enter);
this.ValueControl.Enter += new EventHandler(ValueControl_Enter); this._SearchLookUpEditView.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
this._SearchLookUpEditView.Name = "gridLookUpEdit1View";
this._SearchLookUpEditView.OptionsSelection.EnableAppearanceFocusedCell = false;
this._SearchLookUpEditView.OptionsView.ShowGroupPanel = false;
this.ValueControl.Properties.PopupFormSize = new System.Drawing.Size((int)(this.ValueControl.Width * ), (int)(this.ValueControl.Width * 1.5)); if (this.DesignMode == true)
{
this.Size = new Size(, );
}
}
把自己实际需要用到的属性做好封装,举个栗子:
private int _ItemIndex = -;
/// <summary>
/// 选中项的下标
/// </summary>
[Category("自定义"), Description("ItemIndex,选中项的下标"), Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[McDisplayName("ItemIndex")]
public int ItemIndex
{
get
{
return this._ItemIndex;
}
protected set
{
this._ItemIndex = value;
}
} private DataRow _CurrentItem = null;
/// <summary>
/// 选中项的DataRow对象
/// </summary>
[Category("自定义"), Description("CurrentItem,选中项的DataRow对象"), Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[McDisplayName("CurrentItem")]
public DataRow CurrentItem
{
get
{
return this._CurrentItem;
}
protected set
{
this._CurrentItem = value;
}
} private DataSet _BillDataSet = new DataSet();
/// <summary>
/// 单据的数据源
/// </summary>
[Category("自定义"), Description("BillDataSet,单据的数据源"), Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[McDisplayName("BillDataSet")]
public DataSet BillDataSet
{
get
{
return this._BillDataSet;
}
set
{
this._BillDataSet = value;
}
} /// <summary>
/// 没有多语言的情况下的默认显示标题
/// </summary>
[Category("多语言"), Description("DesigeCaption,没有多语言的情况下的默认显示标题"), Browsable(true)]
[McDisplayName("DesigeCaption")]
public override string DesigeCaption
{
get
{
return this.CaptionControl.Text.Trim();
}
set
{
this.CaptionControl.Text = value;
}
}
也可以根据自己喜好(当然是符合客户习惯的),画蛇添足:
private bool _IsNull = true;
/// <summary>
/// 可空性
/// </summary>
[Category("验证"), Description("IsNull,可空性"), Browsable(true)]
[McDisplayName("IsNull")]
public override bool IsNull
{
get
{
SetBackColor();
return this._IsNull;
}
set
{
this._IsNull = value;
SetBackColor();
}
}
...
/// <summary>
/// 设置背景色
/// </summary>
private void SetBackColor()
{
if (this.ValueControl.Properties.ReadOnly == true)
{
this.ValueControl.BackColor = Color.FromArgb(, , );
}
else
{
if (this._IsNull.Equals(true) == false)
{
this.ValueControl.BackColor = Color.Yellow;
}
else
{
this.ValueControl.BackColor = this._TextBackColor;
}
}
}
当设置控件必填的时候,设置控件的背景色用于区分,具体效果如图:

封装好控件取值,填充值的方法,以及控件数据源绑定的方法(具体根据自己实际项目应用为准,此处只是举个栗子)
/// <summary>
/// 取控件的值
/// </summary>
/// <return>Object</return>
public override object GetValue()
{
DataRowView rowview = null;
BindingSource bs = null;
object v = null; v = this.ValueControl.EditValue == null || this.ValueControl.EditValue == DBNull.Value ? string.Empty : this.ValueControl.EditValue.ToString();
return v;
} /// <summary>
/// 设置控件的值
/// </summary>
/// <param name="value">控件的值</param>
/// <return>int</return>
public override int SetValue(object value)
{
this.ValueControl.EditValue = value == null || value == DBNull.Value ? string.Empty : value;
return ;
} /// <summary>
/// 设置数据绑定
/// </summary>
/// <param name="binding">数据绑定对象</param>
/// <return>int</return>
public override int SetDataBinding(object binding)
{
this.BindingObject = this.ValueControl.DataBindings.Add("EditValue", binding, this.Field, true, DataSourceUpdateMode.OnValidation, string.Empty, this.FormatString);
SetColumnDisplayFormat();
if (binding is BindingSource)
{
int maxlength = ;
if (((BindingSource)binding).DataSource is DataView)
{
if (((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].DataType == typeof(string))
{
maxlength = ((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].MaxLength;
if (maxlength >= )
{
this.MaxLength = maxlength;
}
}
}
else if (((BindingSource)binding).DataSource is DataTable)
{
if (((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].DataType == typeof(string))
{
maxlength = ((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].MaxLength;
if (maxlength >= )
{
this.MaxLength = maxlength;
}
}
}
}
return ;
} /// <summary>
/// 设置下拉框的数据源
/// </summary>
/// <param name="binding">下拉框的数据源</param>
/// <param name="displayMember">显示值字段名</param>
/// <param name="valueMember">实际值字段名</param>
/// <returns>int</returns>
public override int SetSourceTableBinding(object binding, string displayMember, string valueMember)
{
this.DisplayMemberPath = displayMember;
this.SelectedValuePath = valueMember;
this.ValueControl.Properties.DataSource = binding;
this._ResourceDataSource = binding;
return ;
}
完成!为测试效果,在窗体Load事件中造个测试数据,看看效果:
DataTable dataTable = new DataTable("Student");
dataTable.Columns.Add("编号", typeof(String));
dataTable.Columns.Add("昵称", typeof(String));
dataTable.Columns.Add("名称", typeof(String));
dataTable.Rows.Add(new String[] { "", "James", "张三" });
dataTable.Rows.Add(new String[] { "", "Mary", "李四" });
dataTable.Rows.Add(new String[] { "", "Jack", "王五" });
dataTable.Rows.Add(new String[] { "", "joy", "赵六" });
dataTable.Rows.Add(new String[] { "", "jay", "钱七"});
dataTable.Rows.Add(new String[] { "", "stephen", "康忠鑫"});
kzxSearchCbbeSupperStar.SetSourceTableBinding(dataTable, "名称", "昵称");

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



结束语
由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号联系博主,源码可以免费赠予~!有疑问的也可以CALL我一起探讨。
最后,感谢您的耐心陪伴!如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!
玩转控件:封装Dev的SearchLookupEdit的更多相关文章
- 玩转控件:封装Dev的LabelControl和TextEdit
俗话说的好:"工欲善其事必先利其器",作为软件攻城狮也是同样道理,攻城狮开发的软件目的是简化客户的操作,让客户动动手指就可以完成很多事情,减少人力成本.这也是系统/软件存在的目的. ...
- 玩转控件:对Dev的GridControl控件扩展
缘由 一切实现来源于需求,目的在于不盲目造轮子,有小伙伴儿在看了<玩转控件:对Dev中GridControl控件的封装和扩展>文章后,私信作者说,因公司业务逻辑比较复杂,展示字段比较多,尤 ...
- 玩转控件:扩展Dev中SimpleButton
何为扩展,顾名思义,就是在原有控件属性.事件的基础上拓展自己需要或实用的属性.事件等等.或者可以理解为,现有的控件已经不能完全满足我(的需求)了.好的扩展会使控件更加完善,实用,好用.不好的扩展,说白 ...
- 玩转控件:对Dev中GridControl控件的封装和扩展
又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动.... 转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠.裁员的裁员,降薪的降薪,996的996~~说起来都是泪,以 ...
- 玩转控件:Fucking ERP之流程图
前言 首先,跟守护在作者公众号和私信作者催更的朋友们道个歉.疫情的原因,公司从年初到现在一直处于996+的高压模式,导致公众号更新频率较低.而且作者每更新一篇原创公众号,既要对自己沉淀知识负责,也要对 ...
- 玩转控件:重写/重绘Dev中MessageBox弹窗控件
很久没有更新博客了,本想着直接发一篇<手撕ERP>系列,从控件重写.重绘,到框架搭建,再到部分模块实现+业务的.但是每次动手的时候,都觉得难以下手.直接从数据库设计开始吧,模块设计还没定下 ...
- 玩转控件:重绘DEVEXPRESS中DateEdit控件 —— 让DateEdit支持只选择年月 (提供源码下载)
前言 上一篇博文<玩转控件:重绘ComboBox —— 让ComboBox多列显示>中,根据大家的回馈,ComboBox已经支持筛选了,更新见博文最后最后最后面. 奇葩 这两天遇到 ...
- 控件使用经验-MVP模式+控件封装
项目背景 几年前参与了一个面向学校的人事管理软件的开发,基于WinForm平台.今天主要想谈一谈其中关于控件的使用经验.这个项目我们大量使用了第三方控件.由于这个产品的生命周期很长,我们在设计时要考虑 ...
- 尝试使用UISearchDisplayController及对苹果对控件封装习惯的理解
本文转载至 http://blog.sina.com.cn/s/blog_74e9d98d01019vji.html 在之前做过的应用中,很多都有“搜索”这个功能,大部分情况下我都是只采用UISe ...
随机推荐
- Tomcat 之startup.bat启动失败案例
今天我在部署一个Tomcat环境时,各种变量都配置完了,最后启动Tomcat时,Tomcat一闪而过,当时我的内心是崩溃的~~ 然后我就开始百度.定位问题.进入cmd命令行窗口,cd进入到Tomcat ...
- [NodeJS] async 和 await 的本质
绝大多数nodejs程序员都会使用 async 和 await 关键字,但是极少有人能真正弄明白 async 和 await 的原理.这篇文章将从零“构建”出 async 和 await 关 ...
- Jenkins构建项目帮助文档
Jenkins构建项目帮助文档 主要步骤 一.配置jdk 1.1. 下载jdk,安装到自己电脑磁盘的Java目录下(比如:D:\Java\jdk). 1.2. Jdk环境变量的配置: 1. 鼠 ...
- 简说Python之图形初体验
针对孩子,最容易引起小孩的感官认知的就是图形.因此,系统运用图形编程,可以更好地让孩子喜欢上编程. turtle叫做,Turtle graphics.是python第三方的画图模块工具.可以通过imp ...
- Spring注解 - 组件的注册
Spring Boot的出现极大的简化了我们的开发,让我们无需再写繁杂的配置文件,其正是利用了注解的便捷性,而Spring Boot又依赖于Spring,因此深入学习Spring的注解是十分必要的. ...
- vue基础回顾 router
vue-router 1. 底层原理 hash 或者h5 histroy(有兼容性) 2. 使用的时候Vue需要引入VueRouter Vue.use(VueRouter) //VueRouter 底 ...
- Silence主题 美观清爽的cnblog第三方主题
为什么推荐? 才开通cnblog,但苦于官方主题都不是很好看,翻找Github的时候发现了这个项目Silence 这是预览地址 官方展示图片 安装中的坑 不显示公共模块.博文目录.博文签名.博文赞赏. ...
- 使用EPX Studio 7.0 下载网站验证码
implementation var Document_: DispHTMLDocument; //用于处理网页文档对象 EPX: IExcelPanelXDisp; procedure TForm1 ...
- Jenkinsfile里定义对象和函数,获取git提交人, 发送钉钉通知
自从开始使用Jenkinsfile作为Jenkins配置后就一发不可收,因为开发者自定义CI脚本实在太方便了. 比如,最近开发的以一个项目涉及多人,提交冲突挺多的,有的人自己没编译通过就提交了,导致后 ...
- 您知道SASS吗?
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/4-reasons-to-use-sass-in-y ...