最近遇到了一个场景,就是在数据库中没有数据字典的状况下,由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