首页 > 代码库 > C#编写第三方控件,实现窗体控件的一键赋值

C#编写第三方控件,实现窗体控件的一键赋值

                                                         

事出有因

 

 

      在写程序的时候,经常会写上面这样的代码,把查询的结果显示到窗体上,我们怎么做的呢? 一行一行的进行赋值,这样的代码写起来最枯燥,而且还容易出错。大家有没有发现,上面的代码都在做相同的事情—赋值。相类似的代码写了三遍以上,就要考虑是不是能对这个过程进行封装。封装出一个方法,帮我们自动完成这些重复性的操作。

 

 思考过程

 

 

        所接触项目中也有写好的类似方法。只是它涉及到了很多其它的方法,一个套一个,抽离出来特别不方便。而且还有几个令人不爽的地方: 第一是,控件在命名的时候必须和相对应实体属性相同。比如说,姓名这一项,实体的属性名称为sname,那么控件的名称也必须是sname,显然这和我们所遵循的一般命名规范是相违背的。第二是,控件的可见性级别必须设置为Public ,要不然会赋不上值。

       所以,在研究完他的方法后,对它重新进行了编写,做出了一些改进。弥补了上面的两个缺点,使其应用起来更加方便一些。

       所用到的方法,题目中写提到了。编写第三方控件,听着挺高大上,其实就是对C#原有的控件,进行重写,增加一条自己用到的属性而已。在这里增加的属性我将它命名为DataField,用来保存数据库字段的名称。作用嘛?往下看就知道了。。

笔者在这用C#编写了一个Demo,用来说明如何编写第三方控件以及窗体的一键赋值。

 

具体实现过程

 

 

新建一个C#项目

添加一个接口 Interface1:

<span style="font-size:18px;">    interface Interface1
    {       //定义DataField属性
        string DataField { get; set; }

    }</span>

添加两个类ComboxEx、ComboxEx:

 

using System.Windows.Forms;  //添加引用

    internal class TextBoxEx : TextBox, Interface1
    {       //该类继承TextBox控件和接口Interface1
        #region Interface1 成员

        public string DataField
        { get; set; }

        #endregion
    }
    internal class ComboxEx : ComboBox, Interface1
    {
        #region Interface1 成员

        public string DataField
        { get; set; }

        #endregion
    }

 

然后打开工具箱,我们会看到:

                                                                                                 

这就是我们封装的第三方控件。把它拖到窗体上,右击查看其属性

                                                                                            

它多了一条DataField属性,我们可以给他赋上值SID(学生表的字段名—学号)同样再拖拽出几个控件并且赋值。

如图:

                                                                  

    然后开始正式编写代码,添加一个实体类StuEntity

注意:实体属性的名称要和数据库字段名称保持一致!

 

    public class StuEntity
    {
        /// <summary>
        /// 学号
        /// </summary>
        public string SID { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string sname { get; set; }
        /// <summary>
        /// 性别
        /// </summary>
        public string sex { get; set; }
        /// <summary>
        /// 系别
        /// </summary>
        public string department { get; set; }
        /// <summary>
        /// 年级
        /// </summary>
        public string grade { get; set; }
        /// <summary>
        /// 班级
        /// </summary>
        public string sclass { get; set; }
    }

需要说明的一点:这只是一个小Demo并没有采用分层的写法,把编写的方法全部放在了FrmHelper类中

 

    public class FrmHelper
    {
        /// <summary>
        /// 获取实体,将DataTable的行赋值给实体类enStudent
        /// 这里可以采用机房中封装好的方法,将DataTable转换
        /// 成实体类的泛型集合,可以省去这些赋值。
        /// </summary>
        /// <param name="dr">DataTable的行</param>
        /// <returns>返回实体类enStudent</returns>
        public static StuEntity GetEntity(DataRow dr)
        {
            StuEntity enStudent = new StuEntity();
            enStudent.SID = dr["SID"].ToString();
            enStudent.sname = dr["sname"].ToString();
            enStudent.sex = dr["sex"].ToString();
            enStudent.department = dr["department"].ToString();
            enStudent.grade = dr["grade"].ToString();
            enStudent.sclass = dr["sclass"].ToString();
            return enStudent;
        }

        /// <summary>
        /// 将实体类中属性的值,填充到窗体的控件上
        /// </summary>
        /// <param name="enStudent"></param>
        public static void FillFormByEntity(StuEntity enStudent, Form thisfrm)
        {
            //遍历窗体上的控件
            foreach (Control ctrl in thisfrm.Controls)
            {
                //是否继承了接口
                if (ctrl is Interface1)
                {
                    //是否属于文本框
                    if (ctrl is TextBoxEx)
                    {
                        ctrl.Text = GetValue(enStudent, ((TextBoxEx)ctrl).DataField);
                    }//如果属于下拉框
                    else if (ctrl is ComboxEx)
                    {
                        ((ComboxEx)ctrl).Text = GetValue(enStudent, ((ComboxEx)ctrl).DataField);
                    }
                    //如果还有其他类型的控件,可在此进行扩展。
                }
            }
        }
        /// <summary>
        /// 利用反射技术,动态的从实体中获取与控件相对应的值
        /// </summary>
        /// <param name="enStudent">实体类</param>
        /// <param name="DataFiled">字段值</param>
        /// <returns></returns>
        public static string GetValue(StuEntity enStudent, string DataFiled)
        {
            PropertyInfo field = enStudent.GetType().GetProperty(DataFiled);
            return field.GetValue(enStudent, null).ToString();
        }


        /// <summary>
        /// 执行查询语句,返回一个DateTable
        /// </summary>
        /// <returns>DateTable</returns>
        public static DataTable QueryTable()
        {
            using (SqlConnection connection = new SqlConnection("server=.; database=Re_Charge_sys;user id=sa;password=123456"))
            {
                SqlCommand cmd = connection.CreateCommand();
                cmd.CommandText = @"select * from Student_info where SID ='110'";
                DataTable dt = new DataTable();
                DataSet ds = new DataSet();
                try
                {
                    connection.Open();
                    SqlDataAdapter sqlAdapter = new SqlDataAdapter(cmd);
                    sqlAdapter.Fill(ds);
                    dt = ds.Tables[0];
                }
                catch (System.Data.SqlClient.SqlException ex)
                {
                    throw new Exception(ex.Message);
                }
                return dt;
            }
        }
    }


 

客户端调用:

        private void btnFillValue_Click(object sender, EventArgs e)
        { 
            DataTable dt = FrmHelper.QueryTable();
            StuEntity enStudent = FrmHelper.GetEntity(dt.Rows[0]);
            FrmHelper.FillFormByEntity(enStudent, this);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            cmbGrade.Items.AddRange(new String[] { "一年级", "二年级", "三年级", "四年级" });
            cmbSex.Items.AddRange(new String[] { "男", "女" });

            //cmbSex.Items.Add(new KeyValuePair<string, string>("男", "男"));
            //cmbSex.Items.Add(new KeyValuePair<string, string>("女", "女"));
            //cmbSex.DisplayMember = "Key";
            //cmbSex.ValueMember = "Value";
        }


点击赋值按钮,从数据库读取出的数据就会自动填写到界面控件当中。

 

                                       

谈谈第三方控件

 

       当然通过这种方法也能增加其他的属性,比如NotEmpty ,把判断是否为空的方法写在接口里,然后让控件去继承。通过设置该属性的值为 True / False 决定控件内容是否可为空。通过这种方式就避免再去写方法去一个个判断,省时省力。说到这里我不得不感叹一下了:站在巨人的肩膀上。 其实现在互联网上已经有很多已经封装好的,强大的第三方控件。比如说现在所用的C1Studio,对常用控件进行了封装,增加很多特别方便实用的属性,

       不得不说第三方控件现在挺吃香的,因为他给原来死的控件增加了生命力和色彩。

 

写在最后:

 

                做程序员或者说做人,不能太实在、按部就班。

                要多思考,多去寻找能“偷懒”的方法。

                时刻想着,站在巨人的肩膀上。

 

      给窗体控件赋值就写到这里,当然有赋值就有取值,将控件的值赋给实体,传到数据访问层再进行操作。也是MIS系统中经常用到的。方法和赋值类似,具体代码将在下篇博客中呈现给大家。

 

 

oノo═══════════════════════╲ 

│ヽ.学无止境, 分享至上。                                   │ 

│   出自:  http://blog.csdn.net/u010028869     .ヽ│ 

╲═══════════════ヾ

 


 

C#编写第三方控件,实现窗体控件的一键赋值