窗體搭建的效果圖如下:

一:實現的功能主要有以下幾個方面:
①:顯示指定套餐的項目明細
②:向指定套餐添加檢查項目信息
③:刪除套餐中的項目信息
④:新建套餐
二:創建體檢項目維護系統中的檢查項目類(HealthCheckItem)、體檢套餐類(HealthCheckSet)
HealthCheckItem類中的屬性說明如下:
Description:項目描述
Name:項目名稱
Price:項目價格
HealthCheckSet類中的屬性說明如下:
Items:HealthCheckItem的集合。采用泛型集合List<T>作為存儲HealthCheckItem的數據結構
Price:套餐價格,即Items屬性中檢查項目的價格之和
Name:套餐名稱
關鍵代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Chapter05
{
public class HealthCheckItem
{
//項目名
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
//價格
private int price;
public int Price
{
get { return price; }
set { price = value; }
}
//描述
private string description;
public string Description
{
get { return description; }
set { description = value; }
}
public HealthCheckItem(string name,int price,string description)
{
this.Name = name;
this.Price = price;
this.Description = description;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Chapter05
{
public class HealthCheckSet
{
//無參構造中實例化items
public HealthCheckSet()
{
items = new List<HealthCheckItem>();
}
public HealthCheckSet(string name,List<HealthCheckItem>items)
{
this.Name = name;
this.Items = items;
}
//項目名
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
//檢查項目
private List<HealthCheckItem> items;
public List<HealthCheckItem> Items
{
get { return items; }
set { items = value; }
}
//套餐價格
private int price;
public int Price
{
get { return price; }
set { price = value; }
}
//套餐價格計算方法
public void CalcPrice()
{
int totalPrice = 0;
foreach (HealthCheckItem item in items)
{
totalPrice += item.Price;
}
this.price = totalPrice;
}
}
}
三:使用集合來存儲對應的數據,因為套餐 ,體檢項目有多個。定義一些容器來保存數據。
//定義幾個檢查項目
HealthCheckItem height, weight, sight, hearing, liverFun, ekg, bWaves, bloodPressure, bloodTest;
//定義一個系統默認檢查套餐“入學體檢”
HealthCheckSet setA;
//保存所有體檢項目
List<HealthCheckItem> AllItems = new List<HealthCheckItem>();
//保存套餐中的體檢項目
List<HealthCheckItem> items = new List<HealthCheckItem>();
//使用字典保存套餐集合
public Dictionary<string, HealthCheckSet> HealthSet = new Dictionary<string, HealthCheckSet>();
四:初始化保存在AllItems中的所有體檢項目
//初始化檢查項目下拉框值
public void InitItems()
{
height = new HealthCheckItem("身高",5,"用於檢查身高");
weight = new HealthCheckItem("體重", 5, "用於檢查體重.");
sight = new HealthCheckItem("視力", 10, "用於檢查視力.");
hearing = new HealthCheckItem("聽力", 10, "用於檢查聽力.");
liverFun = new HealthCheckItem("肝功能", 50, "用於檢查肝功能.");
bWaves = new HealthCheckItem("B超", 30, "用於檢查B超.");
ekg = new HealthCheckItem("心電圖", 50, "用於檢查心電圖.");
bloodPressure = new HealthCheckItem("血壓", 20, "用於檢查血壓.");
bloodTest = new HealthCheckItem("血常規", 20, "用於檢查血常規.");
AllItems.Add(height);
AllItems.Add(weight);
AllItems.Add(sight);
AllItems.Add(hearing);
AllItems.Add(liverFun);
AllItems.Add(bWaves);
AllItems.Add(ekg);
AllItems.Add(bloodPressure);
AllItems.Add(bloodTest);
//添加請選擇
this.cboItems.Items.Add("請選擇");
foreach (HealthCheckItem item in AllItems)
{
cboItems.Items.Add(item.Name);
}
//默認第一項被選中
this.cboItems.SelectedIndex = 0;
}

五:生成默認套餐數據 以及 加載體檢套餐下拉列表
//生成默認套餐數據
public void InitSets()
{
items = new List<HealthCheckItem>();
items.Add(height);
items.Add(weight);
items.Add(liverFun);
setA = new HealthCheckSet("入學體檢",items);
//計算套餐價格
setA.CalcPrice();
this.HealthSet.Add("入學體檢",setA);
}
//加載體檢套餐下拉列表
public void InitHealthSetList()
{
//首先清空套餐下拉列表
this.cboSets.Items.Clear();
//添加請選擇
this.cboSets.Items.Add("請選擇");
//將Dictionary的Key值綁定到combobox,作為combobox顯示的值
foreach (string key in this.HealthSet.Keys)
{
this.cboSets.Items.Add(key);
}
//默認第一項被選中
this.cboSets.SelectedIndex = 0;
}
六:在Load事件中調用方法
private void frmMain_Load(object sender, EventArgs e)
{
this.lblSetName.Text = "";
this.lblSetPrice.Text = "";
//初始化所有檢查項目
InitItems();
//初始化默認套餐
InitSets();
//加載下拉列表框
InitHealthSetList();
btnAdd.Enabled = false;
btnDel.Enabled = false;
this.dgvHealthList.AutoGenerateColumns = false;
}
七:當套餐下拉框選擇項發生改變時,需要加載所選套餐下對應的體檢項目
//填充套餐的DataGridView
private void UpdateSet(HealthCheckSet set)
{
dgvHealthList.DataSource = new BindingList<HealthCheckItem>(set.Items);
}
//套餐列表
private void cboSets_SelectedIndexChanged(object sender, EventArgs e)
{
string setName = this.cboSets.Text;
if (setName == "請選擇")
{
this.dgvHealthList.DataSource = null;
lblSetName.Text = "";
lblSetPrice.Text = "";
return;
}
//設置套餐名稱
lblSetName.Text = this.HealthSet[setName].Name;
//設置套餐總價
lblSetPrice.Text = this.HealthSet[setName].Price.ToString();
//更新套餐檢查項目
UpdateSet(HealthSet[setName]);
//刪除按鈕為可用狀態
btnDel.Enabled = true;
}
八:在DataGridView中添加項目。判斷是否已經存在要添加的項目,若不在要添加項目的集合中,則執行添加操作
//添加
private void btnAdd_Click(object sender, EventArgs e)
{
if (this.cboItems.SelectedIndex==0)
{
MessageBox.Show("請選擇一個項目!");
return;
}
string cboSetText = this.cboSets.Text;
if (cboSetText == "請選擇")
{
MessageBox.Show("請選擇套餐!");
return;
}
//判斷添加的體檢項目在現有套餐中是否存在
int index = this.cboItems.SelectedIndex-1;
if (!this.HealthSet[cboSetText].Items.Contains(AllItems[index]))
{
this.HealthSet[cboSetText].Items.Add(AllItems[index]);
this.HealthSet[cboSetText].CalcPrice();
UpdateSet(this.HealthSet[cboSetText]);
//刷新窗體集合名稱
this.lblSetName.Text = this.HealthSet[cboSetText].Name;
//刷新窗體集合價格
this.lblSetPrice.Text = this.HealthSet[cboSetText].Price.ToString();
MessageBox.Show("添加成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("該項目已存在!","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
}

九:實現刪除體檢套餐信息
//刪除項目
private void btnDel_Click(object sender, EventArgs e)
{
string setNames = this.cboSets.Text;
if (this.dgvHealthList.SelectedRows.Count == 0)
{
MessageBox.Show("沒有選擇刪除項!","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
return;
}
//獲取選中項目的索引
int index = this.dgvHealthList.SelectedRows[0].Index;
//刪除檢查項
this.HealthSet[setNames].Items.RemoveAt(index);
//重新計算價格
this.HealthSet[setNames].CalcPrice();
//更新DataGridView顯示
UpdateSet(HealthSet[setNames]);
//重設標簽顯示
lblSetName.Text = setA.Name;
string cboSetText = this.cboSets.Text;
lblSetPrice.Text = this.HealthSet[cboSetText].Price.ToString();
MessageBox.Show("刪除成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

十:在套餐列表中添加套餐,通過添加dictionary<K,V>中的Key值來添加套餐,並刷新下拉列表。
//添加套餐
private void btnOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtHealthName.Text))
{
MessageBox.Show("請輸入套餐名稱", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
HealthCheckSet Hch = new HealthCheckSet();
this.HealthSet.Add(this.txtHealthName.Text, Hch);
this.InitHealthSetList();
//向下拉框添加顯示的內容
this.cboSets.SelectedIndex = this.HealthSet.Count;
lblSetName.Text = cboItems.Text;
Hch.Name = cboSets.Text;
MessageBox.Show("添加成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

十一:未添加項目時添加按鈕為禁用狀態,添加時為可用
//檢查項目
private void cboItems_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.cboSets.Text != "請選擇")
{
this.btnAdd.Enabled = true;
}
else
{
this.btnAdd.Enabled = false;
}
}