在我們做客戶關係管理系統的Winform界面的時候,需要對進展階段這個屬性進行一個方便的動態切換和標記處理,如我們根據不同的進展階段顯示不同的相關信息,也可以隨時保存當前的階段信息。其實也是一個比較常見的功能,我們可以把字典列表扁平化動態展示在控制項上,然後根據用戶選擇的階段位置進行切換即可,本篇隨筆... ...
在我們做客戶關係管理系統的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 > 0) { var count = StageList.Count; //計算每項的寬度、高度 var width = (this.Width-150) * 0.8 / (count * 1.0); var height = this.Height * 0.8; //計算間隔位置,預設為0,最大不超過20寬度 double space = 0; if ((count - 1) > 0) { space = (this.Width * 0.2) / ((count - 1) * 1.0); } space = (space > 20) ? 20 : space; //限定最大間隔20 //根據列表項目,動態構建按鈕顯示項目 int i = 0; 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), 0); this.Controls.Add(button); i++; } this.btnSetComplete.Location = new Point(this.Width-145, 4); 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();
實際項目運行的整體效果如下所示。