日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)C#.NET → GridView動(dòng)態(tài)添加數(shù)據(jù)列 數(shù)據(jù)綁定方法

      GridView動(dòng)態(tài)添加數(shù)據(jù)列 數(shù)據(jù)綁定方法

      前往專題相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:本站整理時(shí)間:2011/2/14 8:44:45字體大小:A-A+

      作者:佚名點(diǎn)擊:1564次評(píng)論:0次標(biāo)簽: GridView

      • 類型:編程控件大。15.7M語言:中文 評(píng)分:10.0
      • 標(biāo)簽:
      立即下載
       GridView 是ASP.NET中表格數(shù)據(jù)顯示控件中的一種,可以支持?jǐn)?shù)據(jù)綁定,綁定的數(shù)據(jù)源我們一般用實(shí)現(xiàn)IEnumerable<T>接口的對(duì)象,T可以是任何一個(gè)CLR類(當(dāng)然還有一些其他的數(shù)據(jù)源格式),這些大家基本都很熟悉,但是最近碰到一個(gè)新的需求:

      像有一個(gè)類似于:

      public class Book
      {
      public int ID { get; set; }

      public string Name { get; set; }

      public Dictionary<string, object> ExtendProperties { get; set; }
      }


        其中ExtendProperties 是用來存儲(chǔ)不同用戶自定義的擴(kuò)展屬性的,用鍵值對(duì)的形式保存,Key保存擴(kuò)展屬性名,Value保存擴(kuò)展屬性值,每個(gè)用戶可能的擴(kuò)展屬性個(gè)數(shù)和鍵值都不一樣。

      現(xiàn)在,如果我們需要把List<Book>綁定在GridView上面,但是希望將ExtendProperties中的擴(kuò)展屬性也都顯示出來,而且相應(yīng)的Key顯示在Column的Header,而Value則顯示在相應(yīng)的Cell中。

      起初想沿著GridView綁定一般數(shù)據(jù)的思路考慮,看是否能夠通過動(dòng)態(tài)屬性的方式將ExtendProperties中的鍵值對(duì)匹配成相應(yīng)的對(duì)象屬性,(沒有測(cè)試是否能夠成功),但是又覺得數(shù)據(jù)綁定是控件的事情,這個(gè)不應(yīng)該由數(shù)據(jù)本身來負(fù)責(zé),那我們能否通過修改GridView本身的行為來達(dá)到這個(gè)目的呢?? 答案是肯定的!

      我們都知道,GridView本身是有一個(gè)AutoGenerateColumns的屬性,如果設(shè)置為True的話,GridView將自動(dòng)添加一些列,這些列對(duì)應(yīng)Book中的每一個(gè)可綁定的屬性,這里是用PropertyDescriptor來實(shí)現(xiàn)的(好像是考慮到DesignMode,而沒有用Type來做反射)。根據(jù)這個(gè)思路,我們可以先看看AutoGenerateColumns到底對(duì)GridView有哪些影響以及GridView本身是如何生成Columns的。

      通過查看GridView的源碼,我們可以看到幾個(gè)重要的方法:

      代碼
      protected virtual ICollection CreateColumns(PagedDataSource dataSource, bool useDataSource);

      protected virtual AutoGeneratedField CreateAutoGeneratedColumn(AutoGeneratedFieldProperties fieldProperties);


      其中 CreateColumns方法是GridView用來生成列的,而在其中會(huì)根據(jù)AutoGenerateColumns屬性來判斷是否調(diào)用CreateAutoGenerateColumn來自動(dòng)生成相應(yīng)屬性的列。而且這兩個(gè)方法都是可以重載的,根據(jù)我們的需求,我們可以構(gòu)建一個(gè)GridView的子類,重載 CreateColumns 方法,在 調(diào)用 base.CreateColumns的返回結(jié)果中插入我們希望生成的Column即可。

      代碼如下:

      代碼
      #region Properties

      public bool AutoGenerateExtendPropertiesColumn { get; set; }

      public int AutoGenerateColumnsAfter { get; set; }

      public string ExtendPropertiesDataField { get; set; }

      #endregion

      protected override ICollection CreateColumns(PagedDataSource dataSource, bool useDataSource)
      {
      ICollection collection = base.CreateColumns(dataSource, useDataSource);

      if (AutoGenerateExtendPropertiesColumn )
      {
      ArrayList list = new ArrayList();

      ICollection extendPropertiesCollection = CreateExtendPropertiesColumns(dataSource, useDataSource);

      ArrayList list1 = new ArrayList();
      foreach (var c in collection)
      {
      list1.Add(c);
      }

      ArrayList list2 = new ArrayList();
      if (extendPropertiesCollection != null)
      {
      foreach (var c in extendPropertiesCollection)
      {
      list2.Add(c);
      }
      }

      int copyFrom = AutoGenerateColumnsAfter < list1.Count ? AutoGenerateColumnsAfter : list1.Count - 1;
      copyFrom = copyFrom >= 0 ? copyFrom : -1;

      for (int i = 0; i <= copyFrom; i++)
      {
      list.Add(list1[i]);
      }

      list.AddRange(list2.ToArray());

      for (int i = copyFrom + 1; i < list1.Count; i++)
      {
      list.Add(list1[i]);
      }
      return list;
      }
      return collection;
      }

      protected virtual ICollection CreateExtendPropertiesColumns(PagedDataSource dataSource, bool useDataSource);




      其中我添加了幾個(gè)屬性和一個(gè)新的方法:

      代碼
      public bool AutoGenerateExtendPropertiesColumn { get; set; }

      public int AutoGenerateColumnsAfter { get; set; }

      public string ExtendPropertiesDataField { get; set; }

      protected virtual ICollection CreateExtendPropertiesColumns(PagedDataSource dataSource, bool useDataSource);


      AutoGenerateExtendPropertiesColumn是用來判斷是否要生成擴(kuò)展屬性對(duì)應(yīng)的Column,

      而 AutoGenerateColumnsAfter是用來判斷將自動(dòng)生成的Column應(yīng)該從什么位置開始插入,

      ExtendPropertiesDataField 是用來指明在綁定的對(duì)象中,哪個(gè)屬性是存儲(chǔ)擴(kuò)展屬性的信息的,

      方法 CreateExtendPropertiesColumns是用來生成與ExtendProperties對(duì)應(yīng)的Columns.

      這里只是簡單的舉個(gè)例子,如何通過重載 CreateColumns 方法來實(shí)現(xiàn)自己動(dòng)態(tài)添加Column 的目的。

      現(xiàn)在我們看看如何實(shí)現(xiàn) CreateExtendPropertiesColumns 方法的:

      代碼
      protected virtual ICollection CreateExtendPropertiesColumns(PagedDataSource dataSource, bool useDataSource)
      {
      ArrayList array = new ArrayList();
      if (dataSource.DataSourceCount > 0 && !String.IsNullOrEmpty(ExtendPropertiesDataField))
      {
      var enumerator = dataSource.DataSource.GetEnumerator();
      enumerator.Reset();
      if (enumerator.MoveNext())
      {
      object firstData = enumerator.Current;
      if (firstData != null)
      {
      PropertyDescriptor extendPropertiesDesc = TypeDescriptor.GetProperties(firstData).Find(ExtendPropertiesDataField, false);
      if (extendPropertiesDesc != null && typeof(IEnumerable<KeyValuePair<string, object>>).IsAssignableFrom(extendPropertiesDesc.PropertyType))
      {
      IEnumerable<KeyValuePair<string, object>> extendProperties = (IEnumerable<KeyValuePair<string, object>>)extendPropertiesDesc.GetValue(firstData);
      if (extendProperties != null)
      {
      foreach (var exProperty in extendProperties)
      {
      ExtBouldField bouldField = new ExtBouldField();
      bouldField.UseMethodBinding = true;
      bouldField.MethodName = "GetExtendProperty";
      bouldField.MethodParam = exProperty.Key;
      bouldField.HeaderText = exProperty.Key;
      array.Add(bouldField);
      }
      }
      }
      }
      }
      }
      return array;
      }


      上面的代碼很簡單,就是根據(jù)擴(kuò)展屬性在對(duì)象中的屬性名,獲取相應(yīng)的值,然后再根據(jù)擴(kuò)展屬性構(gòu)建對(duì)應(yīng)的Column,這里有一個(gè)新的自定義的 BouldField: ExtBouldField. 我們知道,一般的 BouldField 都是對(duì)對(duì)象的property進(jìn)行綁定,而我們的數(shù)據(jù)存儲(chǔ)在一個(gè)類型為 Dictionary<string,Object>的 ExtendProperties中,而且希望該Column的HeaderText是Key, Cell中顯示的是Value,這個(gè)是系統(tǒng)的BouldField不能實(shí)現(xiàn)的,那我就自己實(shí)現(xiàn)了一個(gè)可以綁定方法的ExtBouldField (這里只是起到一個(gè)拋磚引玉的作用,功能很簡單,指定一個(gè) MethodName, 和一個(gè)暫時(shí)只能為String類型的MethodParam,這里只能為 String(或者其他基本類型),是為了能夠讓其在ASPX頁面上直接進(jìn)行設(shè)置,如果這些屬性只是純代碼設(shè)置,那么MethodParam可以為任何類型).

      通過分析 BouldField 的源碼,可以了解到 BouldField 對(duì)每一個(gè) DataCell 的數(shù)據(jù)獲取路徑大概是這樣的:

      InitializeCell() -> InitializeDataCell() -> OnDataBouldField() -> GetValue(),

      最后的數(shù)據(jù)獲取途徑是 GetValue() 方法,而且 GetValue() 方法也是可以重載的,那么我們可以重載 GetValue() 方法來實(shí)現(xiàn)按照自己的需求(通過綁定方法而不是綁定屬性的形式)來獲取DataCell的綁定數(shù)據(jù)。為了考慮到原來的基于對(duì)象屬性的綁定形式還可以使用,我還對(duì) InitializeDataCell() 方法做了一些稍微的修改,該 ExtBouldField 的詳細(xì)代碼如下:
      代碼
      public class ExtBouldField :BoundField
      {
      #region Ctor

      public ExtBouldField()
      : base()
      {
      UseMethodBinding = false;
      }

      #endregion

      #region Properties

      public bool UseMethodBinding
      {
      get;
      set;
      }

      public string MethodName
      {
      get;
      set;
      }

      public string MethodParam
      {
      get;
      set;
      }

      #endregion

      #region Overrided methods

      protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
      {
      Control child = null;
      Control control2 = null;
      bool needBinding = (!UseMethodBinding && !String.IsNullOrEmpty(DataField))
      ||(UseMethodBinding && !String.IsNullOrEmpty(MethodName));

      if ((((rowState & DataControlRowState.Edit) != DataControlRowState.Normal) && !this.ReadOnly) || ((rowState & DataControlRowState.Insert) != DataControlRowState.Normal))
      {
      TextBox box = new TextBox();
      box.ToolTip = this.HeaderText;
      child = box;
      if ((needBinding) && ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal))
      {
      control2 = box;
      }
      }
      else if (needBinding)
      {
      control2 = cell;
      }
      if (child != null)
      {
      cell.Controls.Add(child);
      }
      if ((control2 != null) && base.Visible)
      {
      control2.DataBinding += new EventHandler(this.OnDataBindField);
      }
      }

      protected override object GetValue(Control controlContainer)
      {
      if (UseMethodBinding)
      {
      if (String.IsNullOrEmpty(MethodName))
      {
      throw new HttpException("DataItem No MethodName");
      }

      object component = null;
      if (controlContainer == null)
      {
      throw new HttpException("DataControlField_NoContainer");
      }
      component = DataBinder.GetDataItem(controlContainer);

      if (component != null)
      {
      MethodInfo bindingMethodInfo = component.GetType().GetMethod(MethodName);
      if (bindingMethodInfo == null)
      {
      throw new HttpException(String.Format("Not Found the Method:{0}", MethodName));
      }

      return bindingMethodInfo.Invoke(component, new object[] { MethodParam });
      }

      return component;
      }

      return base.GetValue(controlContainer);
      }

      #endregion

      }


      其中:

      UsingMethodBinding 用來指明是用方法綁定還是原來的基于屬性的綁定;

      MethodName 用來指明通過綁定對(duì)象的哪個(gè)方法來獲取綁定數(shù)據(jù);

      MethodParam 用來指明方法的參數(shù)(如果是代碼設(shè)置該屬性的話,可以讓他為任何類型,但是這里只是用string,為了使ASPX頁面也能直接設(shè)置該參數(shù)的值)。

      到這里,原來碰到的問題都解決了:

      通過繼承 GridView 并且重載 CreateColumns() 添加自己想要的 Column,根據(jù)擴(kuò)展屬性中的鍵值對(duì)生成Column。
      通過繼承 BouldField,并且重載 InitializeDataCell() 和 GetValue() 實(shí)現(xiàn)自己希望的綁定方法,實(shí)現(xiàn)可以基于方法的數(shù)據(jù)綁定,從而可以將擴(kuò)展屬性中的鍵值綁定到對(duì)應(yīng)的Cell中。

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無聊無聊

        熱門評(píng)論

        最新評(píng)論

        發(fā)表評(píng)論 查看所有評(píng)論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)