统一的获取,设置UI控件值

在编写WebFormWinForm程序时,我们经常需要编写很多获取,设置UI控件值代码.这确实是一件重复,麻烦而又容易出错的工作.所以我们应该将这个工作交给计算机去做解放我们的劳动力.一般来说UI上的控件都是和我们的EntityObject相对应的,所以利用反射将EntityObject中属性值赋给控件或通过控件填充EntityObject是非常方便的.但是要想让计算机自动干活就要顶一个规则,就是控件ID = 前缀 + 属性名.比如我们有一个User类其定义如下:

class User

    {

        string _name;

        string _pwd;

        public string Name

        {

            get { return this._name; }

            set { this._name = value;}

        }

        public string Pwd

        {

            get { return this._pwd; }

            set { this._pwd = value; }

        }

};

而我们要写一个登录界面,那我们就会有txtNametxtPwd两个文本框来接受输入(我习惯用三个字母缩写来做前缀),这样反射才能派上用场.RoR有条编程理念叫约定由于配置”,我很同意,这可以使我们减少很多无意义的工作.

//控件类型枚举,一些常用的WinFormWebForm控件

public enum CtlType

    {

        TextBox,

        DropDownList,

        ComboBox,

        Hidden,

        CheckBox,

    }

    //值对象和控件根据名字相互映射

    public class ControlHelper

    {

        //id名称前缀表

        public static readonly string[] PreFix_Table = new string[5];

        static ControlHelper()

        {

            PreFix_Table[(int)CtlType.TextBox]      = "txt";

            PreFix_Table[(int)CtlType.DropDownList] = "drp";

            PreFix_Table[(int)CtlType.ComboBox]     = "cmb";

            PreFix_Table[(int)CtlType.Hidden]       = "hdn";

            PreFix_Table[(int)CtlType.CheckBox]     = "chk";

        }

//解析控件名

        private static string ParseCtlID(string id, CtlType ctlType)

        {

            return id.Replace(PreFix_Table[(int)ctlType], "");

        }

}

在上面的代码中我用ParseCtlID方法来得到控件相对应的属性名.

在继续完成这类之前我需要写一个接口IControl来统一访问WinForm ControlWebForm Control类的属性和方法.

//一下五个using语句用来减少输入

using WebFormH = System.Web.UI.HtmlControls;

using WebFormW = System.Web.UI.WebControls;

using WinForms = System.Windows.Forms;

using WebCtl = System.Web.UI.Control;

using WinCtl = System.Windows.Forms.Control;

//统一访问接口

    interface IControl

    {

        object RealCtl                                            //得到真实的控件对象

        {

            get;

        }

        string GetCtlID();                                      //得到控件ID

        IEnumerable<IControl> GetSubCtls();     //得到子控件集合  

    }

    struct WebControl : IControl

    {

        WebCtl _ctl;

        public object RealCtl

        {

            get { return this._ctl; }

        }

        public WebControl(WebCtl ctl)

        {

            this._ctl = ctl;

        }

        public string GetCtlID()

        {

            return this._ctl.ID;

        }

        public IEnumerable<IControl> GetSubCtls()

        {

            foreach (WebCtl c in this._ctl.Controls)

                yield return new WebControl(c);

        }

    };

    struct WinControl : IControl

    {

        WinCtl _ctl;

        public object RealCtl

        {

            get { return this._ctl; }

        }

        public WinControl(WinCtl ctl)

        {

            this._ctl = ctl;

        }

        public string GetCtlID()

        {

            return this._ctl.Name;

        }

        public IEnumerable<IControl> GetSubCtls()

        {

            foreach (WinCtl c in this._ctl.Controls)

                yield return new WinControl(c);

        }

};

好了有了上面的代码我们就能方便来完成剩下的工作了,继续写ControlHelper.遍历和过滤我们需要的子控件,这里使用了Tuple类中的HasType方法进行过滤,GetNullInstance方法来自这里:

private static IEnumerable<IControl> Iterator<_Tuple>(IControl ctl) where _Tuple : Tuple

        {

            Tuple tuple = Tuple.GetNullInstance<_Tuple>();

            foreach (IControl c in ctl.GetSubCtls())

            {

                if (!tuple.HasType(c.RealCtl))

                {

                    foreach (IControl cc in Iterator<_Tuple>(c))

                        yield return cc;

                }

                else

                    yield return c;

            }

        }

最后一步使用反射,这里只贴了WebForm的函数WinForm的类似

//EntityObject的值赋给控件

public static void SetCtlsVal<T>(WebCtl baseCtl, T obj)

        {

//Tuple保存了我们需要的控件类型

            foreach (IControl c in Iterator<Tuple<WebFormW.TextBox,

                                                  WebFormW.DropDownList,

                                                  WebFormH.HtmlInputHidden

                                            >>(new WebControl(baseCtl)))

            {

                if (c.RealCtl is WebFormW.TextBox)

                    ((WebFormW.TextBox)c.RealCtl).Text =

                        QR_Helper<T>.GetPropertyValue_ByName(ParseCtlID(c.GetCtlID(),

                                                             CtlType.TextBox),obj).ToString();

                if (c.RealCtl is WebFormW.DropDownList)

                    ((WebFormW.DropDownList)c.RealCtl).SelectedValue =

                        QR_Helper<T>.GetPropertyValue_ByName(ParseCtlID(c.GetCtlID(),

                                                             CtlType.TextBox), obj).ToString();

                if (c.RealCtl is WebFormH.HtmlInputHidden)

                    ((WebFormH.HtmlInputHidden)c.RealCtl).Value =

                        QR_Helper<T>.GetPropertyValue_ByName(ParseCtlID(c.GetCtlID(),

                                                             CtlType.TextBox), obj).ToString();

            }

        }

Ps: QR_Helper<T>.GetPropertyValue_ByName(ParseCtlID是我写的用来方便放射对象的类,以后会做介绍,当然也可以直接用GetValue().

有了ControlHelper类不但可以很简便的获取,设置控件的值还能实现UI和后台逻辑的解耦.如我们可以借鉴MVC的思想,将一些后台控制逻辑放到Controll类中就可以不需要知道具体是那些UI在使用这个Controll,还是那个User登录的例子

class Controller

    {

        Form _this;

              User _user = new User();

        public Controller(Form thisObj)

        {

            this._this = thisObj;

        }

//验证输入是否正确

              public bool IsValidated()

        {

                     ControlHelper.GetCtlsVal<User>(_this, _user);

            if (this._user.Name != null && this._user.Name != ""

                            && this._user.Pwd != null  && this._user.Pwd != "")

                return true;

            else

                return false;

        }

最后,扩展这个类我们还能实现统一设置UI上控件的Style,或把TextBox都清空这样的操作.

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值