天天看點

WinForm中使用反射将業務對象綁定到窗體或控件容器

在WebForm中,可以使用反射将業務對象綁定到 ASP.NET 窗體控件。最近做Winform項目,也參考WebForm中的代碼實作同樣的功能。

    Winform沒有提供類似WebForm中的FindControl方法,我于是用周遊控件的方式,寫了一個類似WebForm中的這個方法,考慮到Winform中的很多控件放在Label、TabControl中,方法采用了遞歸的方式。

    Winform和Winform的控件也有些差別,如在Winform中,DateTimePicker取值是用Value屬性,在WebForm中使用SelectDate屬性,在Winform中,有NumericUpDown控件,取值也是用Value屬性,是以,具體綁定方式上也和WebForm中有些差別。

////代碼如下:

using System;

using System.Windows.Forms;

using System.Reflection;

using System.Collections;

namespace BindTest

{

    public sealed class FormBinding

    {

        /// <summary>

        /// 将業務對象綁定到窗體或控件容器

        /// </summary>

        /// <param name="obj">業務對象</param>

        /// <param name="container">窗體或控件容器</param>

        public static void BindObjectToControls(object obj, Control container)

        {

            if (obj == null) return;

            Type objType = obj.GetType();

            PropertyInfo[] objPropertiesArray = objType.GetProperties();

            foreach (PropertyInfo objProperty in objPropertiesArray)

            {

                Control control = FindControl(container, objProperty.Name);

                if (control == null) continue;

                if (control is DateTimePicker)

                {

                    DateTimePicker dateTimePicker = (DateTimePicker)control;

                    dateTimePicker.Value = (DateTime)objProperty.GetValue(obj, null);

                }

                else

                    //擷取控件的屬性

                    Type controlType = control.GetType();

                    PropertyInfo[] controlPropertiesArray = controlType.GetProperties();

                    //通用屬性

                    bool success = false;

                    success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool));

                    if (!success)

                        success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String));

                        success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String));

                        success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedValue", typeof(String));

            }

        }

        /// 根據控件名找出容器中的控件,考慮有些控件放在窗體的容器中,采用了遞歸查找。

        /// <param name="container">控件容器</param>

        /// <param name="controlName">控件名稱</param>

        /// <returns></returns>

        private static Control FindControl(Control container, string controlName)

            Control findControl = null;

            foreach(Control control in container.Controls)

                if (control.Controls.Count == 0)

                    if (control.Name == controlName)

                    {

                        findControl = control;

                        break;

                    }

                    findControl = FindControl(control, controlName);

            return findControl;

        /// 設定控件的值

        /// <param name="obj"></param>

        /// <param name="objProperty"></param>

        /// <param name="control"></param>

        /// <param name="controlPropertiesArray"></param>

        /// <param name="propertyName"></param>

        /// <param name="type"></param>

        private static bool FindAndSetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type)

            foreach (PropertyInfo controlProperty in controlPropertiesArray)

                if (controlProperty.Name == propertyName && controlProperty.PropertyType == type)

                    controlProperty.SetValue(control, Convert.ChangeType(objProperty.GetValue(obj, null), type), null);

                    return true;

            return false;

        public static void BindControlsToObject(object obj, Control container)

            //擷取業務對象的屬性  

                    objProperty.SetValue(obj, Convert.ChangeType(dateTimePicker.Value, objProperty.PropertyType), null);

                    success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool));

                        success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String));

                        success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String));

                        success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedValue", typeof(String));

        private static bool FindAndGetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type)

            // 在整個控件屬性中進行疊代

                // 檢查比對的名稱和類型

                if (controlProperty.Name == "Text" && controlProperty.PropertyType == typeof(String))

                    // 将控件的屬性設定為

                    // 業務對象屬性值

                    try

                        objProperty.SetValue(obj, Convert.ChangeType(controlProperty.GetValue(control, null), objProperty.PropertyType), null);

                        return true;

                    catch

                        // 無法将來自窗體控件

                        // 的資料轉換為

                        // objProperty.PropertyType

                        return false;

            return true;

    }

}

//使用方法:

//業務對象:

public class Model

        public Model()

        private string test1;

        private DateTime test2;

        private string test3;

        public string Test1

            set { test1 = value; }

            get { return test1; }

        public DateTime Test2

            set { test2 = value; }

            get { return test2; }

        public string Test3

            set { test3 = value; }

            get { return test3; }

    在一個Winform中,放兩個TextBox控件,一個DateTimePicker控件,一個Panel控件,分别命名位Test1、Test2、Test3,其中把Text3控件放在Panel1中。

    将業務對象綁定到窗體:

Model model = new Model();

model.Test1 = "Hello,World!";

model.Test2 = DateTime.Now.AddMonths(-2);

model.Test3 = "Nice to meet u!";

FormBinding.BindObjectToControls(model, this);

    将窗體綁定到業務對象:

FormBinding.BindControlsToObject(model, this);

MessageBox.Show(model.Test1 + "  " + model.Test2.ToShortDateString() + "  " + model.Test3);