标签:
最近遇到了一个场景,就是在数据库中没有数据字典的情况下,由C#程序临时维护一组类似数据字典功能的类。功能是可以通过键取出值,通过值取出对应的键(仅取第一个匹配的键),类要求具备一定的可扩展性,可以对一些控件(如ComboBox)进行数据源的初始化。因此我自己设计了一个模式,用于实现这个功能。
建立一个Windows窗体应用程序,程序集名为DataDictTest,里面包含窗体FormMain
窗体FormMain中包括一个下拉菜单ComboBox,一个放置在DataGridView中的下拉菜单列,控件摆放如下:
建立一个ComboBox取名cmbWeek
建立一个DataGridView取名dgvTest,添加下拉菜单类型的列,取名colWeek
键值对照基类DataDict,包括三个字段(字典号码DicCode、字典名称DicName、字典备注DicRemark),还有一个数据源DataDic用于保存这些键值对,DataDic包含两列:KEY和TEXT,在键值对照中,KEY的值保存了程序需要识别的值,类似数据字典中某个数据字典项的键;TEXT的值保存给用户真正看到的文字描述,类似于数据字典项中的值。在基类中,可以提供一些用于初始化具体控件的数据源的函数,如下面代码中实现了InitComboBox、InitDataGridViewComboBoxColumn等函数,用于初始化ComboBox控件和DataGridViewComboBoxColumn数据列的数据。
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函数中设置键值对照项。
在FormMain中初始化数据字典:
DictWeek dictWeek = new DictWeek();
并在Load函数中对控件的数据源进行初始化
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
标签:
原文地址:http://my.oschina.net/Tsybius2014/blog/514742