C#语言实现的简易数据键值对照字典类

最近遇到了一个场景,就是在数据库中没有数据字典的情况下,由C#程序临时维护一组类似数据字典功能的类。功能是可以通过键取出值,通过值取出对应的键(仅取第一个匹配的键),类要求具备一定的可扩展性,可以对一些控件(如ComboBox)进行数据源的初始化。因此我自己设计了一个模式,用于实现这个功能。

1、准备工作

建立一个Windows窗体应用程序,程序集名为DataDictTest,里面包含窗体FormMain

124730_hAs7_1425762.png

窗体FormMain中包括一个下拉菜单ComboBox,一个放置在DataGridView中的下拉菜单列,控件摆放如下:

130032_E0vt_1425762.png

建立一个ComboBox取名cmbWeek

建立一个DataGridView取名dgvTest,添加下拉菜单类型的列,取名colWeek

2、建立键值对照基类DataDict

键值对照基类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);
        }
    }
}

3、实现具体的数据键值对照类

有了基类,就可以实现具体的子类对基类继承,通过设置不同的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函数中设置键值对照项。

4、实际应用

在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);
            }
        }
    }
}

5、应用效果

ComboBox的下拉菜单效果

132504_b7m2_1425762.png

下拉菜单取值后,获得选择的键和值:

132505_5l14_1425762.png

DataGridView中的下拉菜单列效果:

132550_DwIQ_1425762.png

下拉菜单列取值后,在该单元格退出编辑状态后显示选中项的键和值:

132550_nzN4_1425762.png

END

转载于:https://my.oschina.net/Tsybius2014/blog/514742

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值