最近遇到了一個場景,就是在數據庫中沒有數據字典的狀況下,由C#程序臨時維護一組相似數據字典功能的類。功能是能夠經過鍵取出值,經過值取出對應的鍵(僅取第一個匹配的鍵),類要求具有必定的可擴展性,能夠對一些控件(如ComboBox)進行數據源的初始化。所以我本身設計了一個模式,用於實現這個功能。數據庫
創建一個Windows窗體應用程序,程序集名爲DataDictTest,裏面包含窗體FormMain函數
窗體FormMain中包括一個下拉菜單ComboBox,一個放置在DataGridView中的下拉菜單列,控件擺放以下:spa
創建一個ComboBox取名cmbWeek設計
創建一個DataGridView取名dgvTest,添加下拉菜單類型的列,取名colWeekcode
鍵值對照基類DataDict,包括三個字段(字典號碼DicCode、字典名稱DicName、字典備註DicRemark),還有一個數據源DataDic用於保存這些鍵值對,DataDic包含兩列:KEY和TEXT,在鍵值對照中,KEY的值保存了程序須要識別的值,相似數據字典中某個數據字典項的鍵;TEXT的值保存給用戶真正看到的文字描述,相似於數據字典項中的值。在基類中,能夠提供一些用於初始化具體控件的數據源的函數,以下面代碼中實現了InitComboBox、InitDataGridViewComboBoxColumn等函數,用於初始化ComboBox控件和DataGridViewComboBoxColumn數據列的數據。orm
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace DataDictTest { /// <summary> /// 鍵值對照基類 /// </summary> class DataDict { /// <summary> /// 獲取數據字典項 /// </summary> /// <returns></returns> private DataTable GetDataDic() { DataTable dt = new DataTable(DicName); dt.Columns.Add("KEY"); //數據字典子項 - 標識字符 dt.Columns.Add("TEXT"); //數據字典子項 - 漢字描述 return dt; } /// <summary> /// 鍵值對照基類 /// </summary> public DataDict() { //數據字典號碼 _dicCode = ""; //數據字典名稱 _dicName = ""; //數據字典備註 _dicRemark = ""; _dataDic = GetDataDic(); } /// <summary> /// 數據字典號碼 /// </summary> protected string _dicCode; /// <summary> /// 數據字典號碼 /// </summary> public string DicCode { get { return _dicCode; } } /// <summary> /// 數據字典名稱(英文標識符) /// </summary> protected string _dicName; /// <summary> /// 數據字典名稱(英文標識符) /// </summary> public string DicName { get { return _dicName; } } /// <summary> /// 數據字典備註 /// </summary> protected string _dicRemark; /// <summary> /// 數據字典備註 /// </summary> public string DicRemark { get { return _dicRemark; } } /// <summary> /// 數據字典內數據 /// </summary> protected DataTable _dataDic; /// <summary> /// 數據字典內數據 /// </summary> public DataTable DataDic { get { return _dataDic; } } /// <summary> /// 初始化控件數據源:ComboBox /// </summary> /// <param name="cmb"></param> public void InitComboBox(ComboBox cmb) { if (cmb == null) { throw new Exception("非法輸入:輸入ComboBox爲空"); } cmb.Items.Clear(); var value = from x in _dataDic.AsEnumerable() select x["TEXT"].ToString(); cmb.Items.AddRange(value.ToArray()); } /// <summary> /// 初始化控件數據源:DataGridViewComboBoxColumn /// </summary> /// <param name="cmb"></param> public void InitDataGridViewComboBoxColumn(DataGridViewComboBoxColumn cmb) { if (cmb == null) { throw new Exception("非法輸入:輸入ComboBox爲空"); } cmb.Items.Clear(); var value = from x in _dataDic.AsEnumerable() select x["TEXT"].ToString(); cmb.Items.AddRange(value.ToArray()); } /// <summary> /// 根據字典鍵獲取字典值 /// </summary> /// <param name="key"></param> /// <returns></returns> public string GetText(string key) { var value = from x in _dataDic.AsEnumerable() where x["KEY"].ToString().Trim() == key.Trim() select x["TEXT"].ToString().Trim(); return value.Count() > 0 ? value.First() : default(string); } /// <summary> /// 根據字典值獲取匹配的第一個鍵 /// </summary> /// <param name="text"></param> /// <returns></returns> public string GetKey(string text) { var value = from x in _dataDic.AsEnumerable() where x["TEXT"].ToString().Trim() == text.Trim() select x["KEY"].ToString().Trim(); return value.Count() > 0 ? value.First() : default(string); } } }
有了基類,就能夠實現具體的子類對基類繼承,經過設置不一樣的KEY-TEXT對,完成不一樣的鍵值對照類。以下面這個類DictWeek,存儲了一週七天的數據鍵值對照:繼承
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace DataDictTest { /// <summary> /// 數據字典:會計年度 /// </summary> internal class DictWeek : DataDict { /// <summary> /// 獲取數據字典項 /// </summary> /// <returns></returns> private DataTable GetDataDic() { DataTable dt = new DataTable(DicName); dt.Columns.Add("KEY"); //數據字典子項 - 標識字符 dt.Columns.Add("TEXT"); //數據字典子項 - 漢字描述 /* ↓↓↓↓這裏輸入數據字典項↓↓↓↓ */ dt.Rows.Add("0", "星期日"); dt.Rows.Add("1", "星期一"); dt.Rows.Add("2", "星期二"); dt.Rows.Add("3", "星期三"); dt.Rows.Add("4", "星期四"); dt.Rows.Add("5", "星期五"); dt.Rows.Add("6", "星期六"); /* ↑↑↑↑這裏輸入數據字典項↑↑↑↑ */ return dt; } /// <summary> /// 星期對照 /// </summary> public DictWeek() : base() { //數據字典號碼 _dicCode = ""; //數據字典名稱 _dicName = ""; //數據字典備註 _dicRemark = ""; _dataDic = GetDataDic(); } } }
在每一個子類中的構造函數中設置數據字典的號碼、名稱、備註,並在GetDataDic函數中設置鍵值對照項。get
在FormMain中初始化數據字典:string
DictWeek dictWeek = new DictWeek();
並在Load函數中對控件的數據源進行初始化it
dictWeek.InitComboBox(cmbWeek);
dictWeek.InitDataGridViewComboBoxColumn( dgvTest.Columns["colWeek"] as DataGridViewComboBoxColumn);
在實際調用數據字典時,不管取出的是鍵或值,均可以調用鍵值對照類中的對應函數(GetText、GetKey)取到另外一半。FormMain中完整的C#代碼以下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace DataDictTest { public partial class FormMain : Form { public FormMain() { InitializeComponent(); } /// <summary> /// 數據字典:星期 /// </summary> DictWeek dictWeek = new DictWeek(); /// <summary> /// Load函數 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormMain_Load(object sender, EventArgs e) { //ComboBox中添加字典數據 dictWeek.InitComboBox(cmbWeek); //DataGridView中的下拉菜單列,添加字典數據 dictWeek.InitDataGridViewComboBoxColumn( dgvTest.Columns["colWeek"] as DataGridViewComboBoxColumn); } /// <summary> /// ComboBox:cmbWeek 值發生變化時觸發 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void cmbWeek_SelectedIndexChanged(object sender, EventArgs e) { string text = cmbWeek.Text; string s = string.Format("KEY: {0}; TEXT: {1}.", dictWeek.GetKey(text), text); MessageBox.Show(s); } /// <summary> /// DataGridView:dgvTest 值發生變化時觸發 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void dgvTest_CellValueChanged(object sender, DataGridViewCellEventArgs e) { //下拉菜單列不存在時,不進行後續操做 if (!dgvTest.Columns.Contains("colWeek")) { return; } //僅下拉菜單列內容發送變化時,顯示數據取值狀況 if (e.ColumnIndex == dgvTest.Columns["colWeek"].Index) { string text = dgvTest.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(); string s = string.Format("KEY: {0}; TEXT: {1}.", dictWeek.GetKey(text), text); MessageBox.Show(s); } } } }
ComboBox的下拉菜單效果
下拉菜單取值後,得到選擇的鍵和值:
DataGridView中的下拉菜單列效果:
下拉菜單列取值後,在該單元格退出編輯狀態後顯示選中項的鍵和值:
END