C#編寫第三方控制項,實現表單控制項的一鍵賦值,

來源:互聯網
上載者:User

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語言中->是什?

->是一個整體,它是用於指向結構體、C++中的class等含有子資料的指標用來取子資料。換種說法,如果我們在C語言中定義了一個結構體,然後申明一個指標指向這個結構體,那麼我們要用指標取出結構體中的資料,就要用到“->”.
舉個例子:
struct Data
{
int a,b,c;
}; /*定義結構體*/
struct Data * p;/*定義結構體指標*/
struct Data A = {1,2,3};/*聲明變數A*/
int x;/*聲明一個變數x*/
p = &A ; /*讓p指向A*/
x = p->a;/*這句話的意思就是取出p所指向的結構體中包含的資料項目a賦值給x*/
/*由於此時p指向A,因而 p->a == A.a,也就是1*/

對於一開始的問題 p = p->next;這應該出現在C語言的鏈表,這裡的next應該是一個與p同類型的結構體指標,其定義格式應該是:
struct Data
{
int a;
struct Data * next;
};/*定義結構體*/
…………
main()
{
struct Data * p;/*聲明指標變數p*/
……
p = p->next;/*將next中的值賦給p*/
}
鏈表指標是C語言的一個痛點,但也是重點,學懂了非常有用。要仔細講就必須先講變數、指標。
什麼是變數?所謂變數,不要淺顯的認為會變得量就是變數。套用我們院長的問話:“教室變不變?”變,因為每天有不同的人在裡面上課,但又不變,因為教室始終在那,沒有變大或變小。這就是變數:有一個不變的地址和一塊可變的儲存空間。正常情況下,我們只看到變數這個房間裡面的東西,也就是其內容,但不會關注變數的地址,但是C語言的指標,就是這個房間的地址。我們聲明變數就相當於蓋了間房子存放東西,我們可以直接觀看房子裡的東西,而聲明指標,就是相當於獲得了一個定位器,當用指標指向某個變數時,就是用指標給變數定位,以後我們就可以用指標找到他所“跟蹤”的變數並可以獲得裡面的內容。
那結構體呢?結構體就相當於是有好幾個房子組成的別墅,幾個房子綁定在一起使用。假設現在有很多這種別墅分布在一個大迷宮裡,每間別墅裡都有一間房子。裡面放了另一個別墅的位置資訊,現在你手拿定位器找到了第一棟別墅,從裡面得到了你想要的東西(鏈表的資料部分),然後把下一棟別墅的位置計入你的定位器(p = p->next),再走向下一棟別墅……如此走下去,知道走到某地下一棟別墅資訊沒有了(p->next == NULL),你的旅行結束。這就是鏈表一次遍曆的過程。現在你能明白 p=p->next的含義了吧!
寫了這麼多。希望你能明白。
如果想學好c和C++,鏈表和指標必須熟練掌握!
 
C語言中->是什?

->是一個整體,它是用於指向結構體、C++中的class等含有子資料的指標用來取子資料。換種說法,如果我們在C語言中定義了一個結構體,然後申明一個指標指向這個結構體,那麼我們要用指標取出結構體中的資料,就要用到“->”.
舉個例子:
struct Data
{
int a,b,c;
}; /*定義結構體*/
struct Data * p;/*定義結構體指標*/
struct Data A = {1,2,3};/*聲明變數A*/
int x;/*聲明一個變數x*/
p = &A ; /*讓p指向A*/
x = p->a;/*這句話的意思就是取出p所指向的結構體中包含的資料項目a賦值給x*/
/*由於此時p指向A,因而 p->a == A.a,也就是1*/

對於一開始的問題 p = p->next;這應該出現在C語言的鏈表,這裡的next應該是一個與p同類型的結構體指標,其定義格式應該是:
struct Data
{
int a;
struct Data * next;
};/*定義結構體*/
…………
main()
{
struct Data * p;/*聲明指標變數p*/
……
p = p->next;/*將next中的值賦給p*/
}
鏈表指標是C語言的一個痛點,但也是重點,學懂了非常有用。要仔細講就必須先講變數、指標。
什麼是變數?所謂變數,不要淺顯的認為會變得量就是變數。套用我們院長的問話:“教室變不變?”變,因為每天有不同的人在裡面上課,但又不變,因為教室始終在那,沒有變大或變小。這就是變數:有一個不變的地址和一塊可變的儲存空間。正常情況下,我們只看到變數這個房間裡面的東西,也就是其內容,但不會關注變數的地址,但是C語言的指標,就是這個房間的地址。我們聲明變數就相當於蓋了間房子存放東西,我們可以直接觀看房子裡的東西,而聲明指標,就是相當於獲得了一個定位器,當用指標指向某個變數時,就是用指標給變數定位,以後我們就可以用指標找到他所“跟蹤”的變數並可以獲得裡面的內容。
那結構體呢?結構體就相當於是有好幾個房子組成的別墅,幾個房子綁定在一起使用。假設現在有很多這種別墅分布在一個大迷宮裡,每間別墅裡都有一間房子。裡面放了另一個別墅的位置資訊,現在你手拿定位器找到了第一棟別墅,從裡面得到了你想要的東西(鏈表的資料部分),然後把下一棟別墅的位置計入你的定位器(p = p->next),再走向下一棟別墅……如此走下去,知道走到某地下一棟別墅資訊沒有了(p->next == NULL),你的旅行結束。這就是鏈表一次遍曆的過程。現在你能明白 p=p->next的含義了吧!
寫了這麼多。希望你能明白。
如果想學好c和C++,鏈表和指標必須熟練掌握!
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.