WinForm中使用反射將業務對象綁定到表單或控制項容器

來源:互聯網
上載者:User

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

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

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

                }
            }
        }

       
        /// <summary>
        /// 根據控制項名找出容器中的控制項,考慮有些控制項放在表單的容器中,採用了遞迴尋找。
        /// </summary>
        /// <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;
                    }
                }
                else
                {
                    findControl = FindControl(control, controlName);
                }
            }
            return findControl;
        }

        /// <summary>
        /// 設定控制項的值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="objProperty"></param>
        /// <param name="control"></param>
        /// <param name="controlPropertiesArray"></param>
        /// <param name="propertyName"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        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)
        {
            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;
                    objProperty.SetValue(obj, Convert.ChangeType(dateTimePicker.Value, objProperty.PropertyType), null);

                }
                else
                {
                    Type controlType = control.GetType();
                    PropertyInfo[] controlPropertiesArray = controlType.GetProperties();

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

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

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

                    if (!success)
                        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)
        {
            // 在整個控制項屬性中進行迭代
            foreach (PropertyInfo controlProperty in controlPropertiesArray)
            {
                // 檢查匹配的名稱和類型
                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);

    將表單綁定到業務對象:
Model model = new Model();
FormBinding.BindControlsToObject(model, this);
MessageBox.Show(model.Test1 + "  " + model.Test2.ToShortDateString() + "  " + model.Test3);

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.