在我们做客户关系管理系统的Winform界面的时候,需要对进展阶段这个属性进行一个方便的动态切换和标记处理,如我们根据不同的进展阶段显示不同的相关信息,也可以随时保存当前的阶段信息。其实也是一个比较常见的功能,我们可以把字典列表扁平化动态展示在控件上,然后根据用户选择的阶段位置进行切换即可,本篇随笔就是在客户的需求基础上完善这个功能。

1、进展阶段的动态展示和处理

我们来看看界面的大致情况

其实这部分是根据字典列表进行动态展示的,也就是使用一个用户控件进行处理即可。

为了实现这个功能,我们先创建一个用户控件,如下界面所示,保留一个按钮,这个我们让它先占着位置,最后还是把它追加到最后的位置上即可。

为了展示所有阶段,并记录当前阶段,我们设置了两个变量,放在用户控件里面

        /// <summary>
/// 阶段列表
/// </summary>
public List<CListItem> StageList { get; set; }
/// <summary>
/// 当前阶段的值
/// </summary>
public double CurrentStage { get; set; }

然后为了在切换和保存两个事件触发外部处理,我们添加两个事件处理,如下所示

        /// <summary>
/// 选中某个阶段的处理事件
/// </summary>
public EventHandler OnSelectedStageHandler { get; set; }
/// <summary>
/// 设置阶段完成的处理事件
/// </summary>
public EventHandler OnSetCompleteStage { get; set; }

这样用户控件看起来就像是这样子的代码了。

    /// <summary>
/// 阶段控件显示
/// </summary>
public partial class StageControl : BaseUserControl
{
/// <summary>
/// 阶段列表
/// </summary>
public List<CListItem> StageList { get; set; }
/// <summary>
/// 当前阶段的值
/// </summary>
public double CurrentStage { get; set; }
/// <summary>
/// 选中某个阶段的处理事件
/// </summary>
public EventHandler OnSelectedStageHandler { get; set; }
/// <summary>
/// 设置阶段完成的处理事件
/// </summary>
public EventHandler OnSetCompleteStage { get; set; }

为了动态展示控件的信息,我们需要使用一个自定义函数来对控件按钮的位置进行判断并绘制,这样可以根据需要进行相关样式的定义,也可以动态变化阶段的列表内容。

        /// <summary>
/// 初始化控件
/// </summary>
public void Init()
{
this.Controls.Clear();//清空界面 //根据阶段列表数量计算每个选项的大小
if (StageList != null && StageList.Count > )
{
var count = StageList.Count;
//计算每项的宽度、高度
var width = (this.Width-) * 0.8 / (count * 1.0);
var height = this.Height * 0.8; //计算间隔位置,默认为0,最大不超过20宽度
double space = ;
if ((count - ) > )
{
space = (this.Width * 0.2) / ((count - ) * 1.0);
}
space = (space > ) ? : space; //限定最大间隔20 //根据列表项目,动态构建按钮显示项目
int i = ;
foreach (CListItem item in StageList)
{
double value = Convert.ToDouble(item.Value);
SimpleButton button = new SimpleButton();
button.Text = value.ToString("P0");//显示百分比
button.ToolTip = item.Text;
button.Tag = value;
button.ButtonStyle = BorderStyles.HotFlat;
button.Appearance.Options.UseBackColor = true;
//根据所处阶段设置背景色
if(CurrentStage >= value)
{
button.Appearance.BackColor = Color.SkyBlue;
}
else
{
button.Appearance.BackColor = Color.Transparent;
} //按钮的单击事件,触发对外部的处理
button.Click += (s,e)=>
{
var currentStep = (SimpleButton)s;
CurrentStage = Convert.ToDouble(currentStep.Tag);
if(OnSelectedStageHandler != null)
{
OnSelectedStageHandler(s, e);
}
Init(); };
//根据计算好的信息,设置按钮大小和位置
button.Size = new Size((int)width, (int)height);
button.Location = new Point(i * (int)(width + space), );
this.Controls.Add(button); i++;
} this.btnSetComplete.Location = new Point(this.Width-, );
this.Controls.Add(btnSetComplete);
}
}

如果是要保存状态,也交由事件处理

        /// <summary>
/// 完成操作,触发外部对状态的保存
/// </summary>
private void btnSetComplete_Click(object sender, EventArgs e)
{
if(OnSetCompleteStage != null)
{
OnSetCompleteStage(sender, e);
}
}

2、外部窗体使用自定义控件

创建好用户控件后,在外部窗体使用这个用户控件的时候,我们把它拖到窗体界面里面,如下设计界面效果所示。

在这个窗体里面,初始化控件的事件处理,用来做选择的变化处理和保存状态处理。

            this.stageControl1.OnSelectedStageHandler += (s, e) =>
{
this.txtStage.SetComboBoxItem(string.Concat(this.stageControl1.CurrentStage));
};
this.stageControl1.OnSetCompleteStage += (s, e) =>
{
if (!string.IsNullOrEmpty(ID))
{
this.txtStage.SetComboBoxItem(string.Concat(this.stageControl1.CurrentStage));
var result = CallerFactory<ISaleChanceService>.Instance.UpdateStage(tempInfo.ID, this.stageControl1.CurrentStage);
ShowMessageAutoHide(result.Success ? "设置成功" : "设置失败");
ProcessDataSaved(null, null);
}
};

我们在调用窗体使用这个进展阶段的控件的时候,需要给它初始化数据,如下是对字典信息的绑定给它。

        /// <summary>
/// 初始化数据字典
/// </summary>
private void InitDictItem()
{
//初始化代码
this.txtStatus.BindDictItems("机会状态");
this.txtSource.BindDictItems("机会来源");
this.txtChanceType.BindDictItems("机会类别"); this.txtCompetitiveIndex.BindDictItems("机会竞争指数");
this.txtConfidenceIndex.BindDictItems("机会信心指数");
this.txtStage.BindDictItems("机会进展阶段"); var listItem = DictItemUtil.GetDictByDictType("机会进展阶段");
this.stageControl1.StageList =
listItem;
}

然后在界面显示的时候,调用Init函数即可,如下代码所示。

            //初始化显示控件
this.stageControl1.Init();

实际项目运行的整体效果如下所示。

在Winform系统界面中对进展阶段的动态展示和处理的更多相关文章

  1. Winform界面中实现菜单列表的动态个性化配置管理

    在我们一般的应用系统里面,由于系统是面向不同类型的用户,我们所看到的菜单会越来越多,多一点的甚至上百个,但是我们实际工作接触的菜单可能就是那么几个,那么对于这种庞大的菜单体系,寻找起来非常不便.因此对 ...

  2. 在Winform框架界面中改变并存储界面皮肤样式

    在本篇介绍的Winform界面样式改变及存储操作中,是指基于DevExpress进行界面样式的变化.一般情况下,默认我们会为客户提供多种DevExpress的界面皮肤以供个人喜好选择,默认DevExp ...

  3. 如何快速开发树形列表和分页查询整合的WInform程序界面

    我在做Winform界面的时候,一般都是统一化处理,界面顶部放置一些字段条件供查询,下面就是分页查询列表,展示相关的数据.但有时候碰到一些表字段内容分类比较多,有一些特别重要,如果放在一个树形列表来进 ...

  4. Web API应用架构在Winform混合框架中的应用(5)--系统级别字典和公司级别字典并存的处理方式

    在我这个系列中,我主要以我正在开发的云会员管理系统为例进行介绍Web API的应用,由于云会员的数据设计是支持多个商家公司,而每个公司又可以包含多个店铺的,因此一些字典型的数据需要考虑这方面的不同.如 ...

  5. Web API应用架构在Winform混合框架中的应用(3)--Winfrom界面调用WebAPI的过程分解

    最近一直在整合WebAPI.Winform界面.手机短信.微信公众号.企业号等功能,希望把它构建成一个大的应用平台,把我所有的产品线完美连接起来,同时也在探索.攻克更多的技术问题,并抽空写写博客,把相 ...

  6. 在Winform框架的多文档界面中实现双击子窗口单独弹出或拖出及拽回的处理

    在基于DevExpress的多文档窗口界面中,我们一般使用XtraTabbedMdiManager来管理多文档窗口的一些特性,如顶部菜单,页面的关闭按钮处理,以及一些特殊的设置,本篇随笔介绍这些特点, ...

  7. 在Winform界面中实现对多文档窗体的参数传值

    在Winform界面中窗体我们一般使用多文档进行展示,也就是类似一般的选项卡的方式可以加载多个窗体界面.一般来说,我们如果打开新的窗体,给窗体传递参数是很容易的事情,但是在框架层面,一般的窗体是通过动 ...

  8. Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面

    现在开发中的功能需要直接跳转到拨号.联系人.短信界面等等,查找了很多资料,自己整理了一下. 1.跳转到拨号界面,代码如下: 1)直接拨打 Intent intentPhone = new Intent ...

  9. Winform界面中主从表编辑界面的快速处理

    在Winform开发中,我们往往除了常规的单表信息录入外,有时候设计到多个主从表的数据显示.编辑等界面,单表的信息一般就是控件和对象实体一一对应,然后调用API保存即可,主从表就需要另外特殊处理,本随 ...

随机推荐

  1. 开源:ASP.NET Aries 开发框架(已支持.NET Core)

    前言: 随着岁月的推进,不知不觉已在.NET这领域上战斗了十年了. 青春还没来得急好好感受,却已是步入健忘之秋的老人一枚了. 趁着还有点记忆,得赶紧把硬盘里那私藏的80G除外的东西,和大伙分享分享. ...

  2. 最短路问题之Dijkstra算法

    题目: 在上一篇博客的基础上,这是另一种方法求最短路径的问题. Dijkstra(迪杰斯特拉)算法:找到最短距离已经确定的点,从它出发更新相邻顶点的最短距离.此后不再关心前面已经确定的“最短距离已经确 ...

  3. VS Code实用技能1 - 代码折叠、面包屑

    VS Code实用技能 VS Code实用技能1 - 代码折叠.面包屑 一.代码折叠 ubuntu ctrl + shift + { ctrl + shift + } ctrl + k , ctrl ...

  4. lambda和匿名内部类使用外部变量为什么要语义final?

    今天群里讨论java的lambda实现. 后来不断衍生谈到了为什么lambda和匿名内部类只能使用语义final的外部变量. 最开始以为是java的lambda实现问题,编译期魔法会把外部引用作为参数 ...

  5. 使用 Moq 测试.NET Core 应用 - Why Moq?

    什么是Mock 当对代码进行测试的时候, 我们经常需要用到一些模拟(mock)技术. 绿色的是需要被测试的类, 黄色是它的依赖项, 灰色的无关的类 在一个项目里, 我们经常需要把某一部分程序独立出来以 ...

  6. 记一次自己在Linux上倒腾Nginx的经历

    自己装了个CenterOS7.5,还装了个.NET Sdk,又装了个nginx...学会几个命令 su root rm - rf helloCore 删除文件夹及文件 输入命令行: ps -ef | ...

  7. 《前端之路》之五 head 头标签指南

    12:head 头标签指南 常见头标签 DOCTYPE 文档模式 对文档进行有效性验证 告诉用户代理或浏览器这个文档是按照什么DTD写的,但是这个动作是被动的,每次页面加载时,浏览器并不会下载DTD, ...

  8. 【Android Studio安装部署系列】三十一、从Android studio3.0.0升级到Android studio3.0.1

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 突然想要升级到较高版本.要跟随潮流嘛,不然就落后了. 下载IDE http://www.wanandroid.com/tools/i ...

  9. Devexpress常见问题

    1.DevExpress控件组中的GridControl控件不能使横向滚动条有效. 现象:控件中的好多列都挤在一起,列宽都变的很小,根本无法正常浏览控件单元格中的内容. 解决:gridView1.Op ...

  10. 阿里云Ubuntu下安装、配置权限和导入本地mongodb

    ---恢复内容开始--- 第一部分:首先先在Ubuntu下安装好mongodb,步骤如下: 首先我们需要借助远程管理工具链接到阿里云上的ubuntu系统,接着进行如下操作 一.导出软件源的公钥 sud ...