程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 統一的獲取,設置UI控件值

統一的獲取,設置UI控件值

編輯:關於C#

在編寫WebForm或WinForm程序時,我們經常需要編寫很多獲取,設置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; }
    }
};

而我們要寫一個登錄界面,那我們就會有txtName和txtPwd兩個文本框來 接受輸入(我習慣用三個字母縮寫來做前綴),這樣反射才能派上用場.RoR有條編程理念叫 ”約定由於配置”,我很同意,這可以使我們減少很多無意義的工作.

//控 件類型枚舉,一些常用的WinForm和WebForm控件

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 Control和WebForm 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都清空這樣的操作.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved