在不少时候,咱们作一些很是规化的界面的时候,每每须要建立一些用户控件,在其中绘制好一些基础的界面块,做为后续重复使用的一个单元,用户控件同时也能够封装处理一些简单的逻辑。在开发Winform各类类型项目,我都时不时须要定制一些特殊的用户控件,以方便在界面模块中反复使用。咱们通常是在自定义的用户控件里面,添加各类各样的界面控件元素,或者封装一些特殊的函数处理共外部调用等。本篇随笔主要介绍基于DevExpress的Winform开发经验,介绍一个相似看板信息的用户控件,并在TabelLayout和StackLayout布局控件中进行展现。函数
在偶尔的一个场合下,看到一个牙医管家的软件界面作的很是不错,其中有一个预定列表的界面感受很是好,以下界面所示。布局
其中它的每一个用户信息列表里面,都是一个综合信息的展现,很是直观,估计应该是用户自定义控件作的。测试
在其中里面,有不一样的字体,各式图标,以及内容的信息展现, 这个我在DevExpress的列表控件里面,没有看到能够如此定义列表内容的,在DevExpress的GridView里面有一个看板模板的定义有点接近,可是试了一下,可调性很差,因而放弃寻求其余接近方案,玩遍DevExpress的控件后,发现最好的方式应该是自定义用户控件的方式来解决这个界面问题。字体
花了一点时间,制做了一个用户控件,在其中添加一个LayoutControl方便控制布局,添加一些标签以及设置了一些图标,获得下图所示。this
左侧的颜色条因为使用Group控件,所以宽度暂时没法调整,若是介意大小,咱们能够在其中在建立一个LayoutControl,而后在其中方式内容便可。spa
咱们改变布局,而后添加一个颜色块,获得相似界面以下所示。code
咱们来定义一下用户控件的源码部分,修改其中源码,增长对应的属性,方便动态设置用户控件的相关属性,如颜色块,项目背景色,以及绑定的对象信息等内容。orm
而后在界面加载完毕后,设置对应的信息和颜色信息,以下代码所示。对象
/// <summary> /// 窗口加载事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UserItemControl_Load(object sender, EventArgs e) { BindData(); RefreshColor(); } /// <summary> /// 根据用户定义信息,显示不一样的内容 /// </summary> private void BindData() { if(this.UserItemInfo != null) { var info = this.UserItemInfo; this.lblCustomerName.Text = info.CustomerName; this.lblMobile.Text = info.Mobile; this.lblReceiver.Text = info.Receiver; this.lblRecordDate.Text = info.RecordDate; this.lblRecordNo.Text = info.RecordNo; this.lblDealType.Text = ""; this.lblStar.ImageOptions.ImageIndex = GetStarImageIndex(info.Stars); if (!info.IsVip) { this.lblVip.Visibility = LayoutVisibility.Never; } } } /// <summary> /// 刷新背景色 /// </summary> private void RefreshColor() { if (ItemBlockColor != Color.Empty) { this.itemColor.AppearanceItemCaption.BackColor = ItemBlockColor; } if (ItemBackColor != Color.Empty) { layoutControl1.BackColor = ItemBackColor; } }
但咱们鼠标浮动在项目上或者离开的时候,或者单击某项的时候,咱们变换下颜色,方便区分显示。blog
private void layoutControl1_MouseLeave(object sender, EventArgs e) { if (!this.IsSelected) { this.layoutControl1.ResetBackColor(); } } private void layoutControl1_MouseEnter(object sender, EventArgs e) { if (!this.IsSelected) this.layoutControl1.BackColor = Color.FromArgb(192, 255, 192); } private void layoutControl1_Click(object sender, EventArgs e) { this.IsSelected = true; OnItemClick?.Invoke(this, e); }
完成这些后,咱们须要在窗体上对内容进行初始化。
最后咱们看看界面的效果以下所示
或者下面这样的界面布局。
若是嫌弃边框红色很差看,咱们 能够修改边框为灰色调一点的,这样整体看起来效果以下所示。
获得和咱们最终须要的界面很接近了。
通常除了悬浮鼠标颜色变化外,控件单击后,咱们会设置不一样的背景色,以示区分。
/// <summary> /// 是否选中节点 /// </summary> public bool IsSelected { get { return m_IsSelected; } set { m_IsSelected = value; this.ItemBackColor = value ? Color.FromArgb(255, 255, 192) : Color.Transparent; this.RefreshColor(); } }
通常列表界面中,咱们除了支持鼠标移动、单击变色的效果外,咱们还但愿支持经过键盘箭头上下键进行上下浏览项目。咱们若是须要使用键盘的按键,须要设置窗体的KeyPreview属性为True,
而后跟踪按键的事件便可,以下所示。
this.KeyPreview = true; this.KeyUp += FrmKanBan_KeyUp;
按键事件捕捉处理以下所示,主要就是判断选中的用户控件,并对面板的子控件的选中效果进行处理。
private void FrmKanBan_KeyUp(object sender, KeyEventArgs e) { //单击鼠标或者切换按键,会触发用户控件得到selectItem对象,能够进行箭头上下移动 if (selectItem != null) { var panel = selectItem.Parent; if (panel != null) { //获取操做项的索引值 int oldIndex = panel.Controls.IndexOf(selectItem); if (e.KeyCode == Keys.Up) { if (oldIndex > 0) { //经过序号得到新的控件,并单击它触发选择事件 var newCtrl = panel.Controls[oldIndex - 1]; Item_OnItemClick(newCtrl, new EventArgs()); } } else if (e.KeyCode == Keys.Down) { if (oldIndex < (panel.Controls.Count - 1)) { //经过序号得到新的控件,并单击它触发选择事件 var newCtrl = panel.Controls[oldIndex + 1]; Item_OnItemClick(newCtrl, new EventArgs()); } } } } }
界面中用户控件的切换选中效果,须要先清空以前全部的选择,而后在设置新的选中控件,因此还须要对控件触发单击事件进行处理,以下所示。
/// <summary> /// 选中的用户控件对象实例 /// </summary> UserItemControl selectItem = null; /// <summary> /// 单击用户控件,触发清除全部标记后,再次设置选中的项目标记 /// </summary> private void Item_OnItemClick(object sender, EventArgs e) { //清空全部控件的选中标记 var panel = (PanelControl)((Control)sender).Parent; foreach (Control ctrl in panel.Controls) { var item = ctrl as UserItemControl; if(item != null) { item.IsSelected = false; } } //设置选中控件 selectItem = ((UserItemControl)sender); selectItem.IsSelected = true; this.Text = selectItem.UserItemInfo.CustomerName + "-选中"; //若是在面板中遮挡,移动滚动条,能够查看到完整用户控件界面 panel.ScrollControlIntoView(selectItem); }
以下效果所示。
咱们在作Winform开发的时候,通常知道,微软传统Winform的布局提供两个控件,FlowLayoutPanel和TableLayoutPanel,一个是流式布局,一个是表格布局,各有各的用处。流式布局主要就是按照顺序挨个放置控件,表格布局主要按照表格的定义的行列单元格,严格放置控件,表格单元格控制强度更大,并且控件具备拉伸效果。
对于DevExpress,咱们通常仍是倾向于采用它提供给的控件来作界面,能够很好融合它的皮肤效果,相对于Winform传统两个布局控件,DevExpress提供了两个封装效果至关的控件布局StackPanel和 TablePanel,他们的效果实现大同效果,不过调用的接口不一样。
对于两个控件,咱们但愿里面的内容自动出现滚动条,那么设置属性AutoScroll 为True便可,以下代码所示。
panel.AutoScroll = true;
而StackPanel另外须要LayoutDirection,也就是控件顺序展示的方式,以下代码所示。
panel.LayoutDirection = StackPanelLayoutDirection.TopDown;
使用StackPanel面板来测试展现用户控件列表的界面代码以下所示。
/// <summary> /// 使用StackPanel对用户控件布局进行处理 /// </summary> private void InitPanel(StackPanel panel) { panel.AutoScroll = true;//面板自动出现滚动条 panel.LayoutDirection = StackPanelLayoutDirection.TopDown;//从上往下展现 panel.Controls.Clear();//清空界面 var list = GetInfoList(); //获取用户控件绑定的对象信息列表 for (int i = 0; i < list.Count; i++) { //定义用户控件实例 var item = new UserItemControl(); item.UserItemInfo = list[i];//绑定对象信息 item.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; item.ItemBlockColor = colors[i %10]; //变化颜色 item.OnItemClick += Item_OnItemClick;//触发选中事件 panel.Controls.Add(item); } }
对于表格布局TablePanel控件来讲,使用初始化控件的方式也差很少,不过有个别地方注意便可。
/// <summary> /// 使用TablePanel对用户控件布局进行处理 /// </summary> private void InitPanel(TablePanel panel) { panel.AutoScroll = true;//面板自动出现滚动条 panel.Controls.Clear();//清空界面 panel.Rows.Clear();//清空行 panel.Columns.Clear();//清空列 //添加列定义(增长一个列便可) panel.Columns.Add(new TablePanelColumn(TablePanelEntityStyle.Relative, 55F)); var list = GetInfoList(); //获取用户控件绑定的对象信息列表 for (int i = 0; i < list.Count; i++) { //定义行信息 panel.Rows.Add(new TablePanelRow(TablePanelEntityStyle.AutoSize, 100F)); //定义用户控件实例 var item = new UserItemControl(); item.UserItemInfo = list[i]; //定义拉伸效果 item.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; item.ItemBlockColor = colors[i % 10]; //变化颜色 item.OnItemClick += Item_OnItemClick;//触发选中事件 //先添加控件到面板集合中 panel.Controls.Add(item); //设置控件的单元格位置 panel.SetCell(item, i, 0); } //添加多一行,确保布局 panel.Rows.Add(new TablePanelRow(TablePanelEntityStyle.AutoSize, 100F)); }
添加控件的时候,须要注意下面的代码,才能正常展现控件信息,不然没法看到用户控件。
//先添加控件到面板集合中 panel.Controls.Add(item); //设置控件的单元格位置 panel.SetCell(item, i, 0);
最后对比下效果,左边是TablePanel,右边是StackPanel展示出来的效果。
以上就是界面如何在DevExpress开发中使用各类用户控件进行用户控件的建立、以及实现鼠标进入、移出、单击的不一样效果,以及实现键盘上下箭头按键的事件选中效果,并介绍DevExpress中两个布局控件TabelPanel和StackPanel的正常使用,达到展现控件信息的做用。