2013-09-24 5 views
0

Я хочу, чтобы создать пользовательский элемент управления сервером, который выглядит следующим образом:Поддержки вложенных элементов в ASP.Net пользовательского сервере управления

<cc:MyControl prop1="a" prop2="b"> 
    <cc:MyItem name="xxx"> 
    <cc:MyItem name="yyy"> 
    <cc:MyItem name="zzz"> 
</cc:MyControl> 

MyControl, конечно, реализованные в качестве серверного элемента управления, однако я не хотят MyItem - дочерний элемент управления. Скорее они должны существовать как простые объекты .Net. У меня есть класс MyItem, а элемент управления имеет свойство «Элементы», и когда элементы MyItem объявлены в разметке, объекты должны быть созданы и добавлены в коллекцию.

Учебники по MSDN на самом деле не объясняют, как это происходит. См: http://msdn.microsoft.com/en-us/library/9txe1d4x.aspx

Я хотел бы знать:

  1. Как <cc:MyItem> переходит в класс MyItem? Должен ли элемент в разметке иметь то же имя, что и класс объекта?
  2. Какой конструктор MyItem вызывается, когда MyItems добавляются декларативно и когда?
  3. Какие типы коллекций мне разрешено использовать для хранения объектов MyItem? В приведенной выше ссылке используется ArrayList, но могу ли я использовать строго типизированный список?
  4. Возможно ли, чтобы элемент управления содержал несколько коллекций?

ответ

0
  1. Это настолько часто, чтобы использовать имя класса для разметки, но вы можете присвоить другое имя, если вы хотите, я не буду говорить больше, если вы хотите, пожалуйста, комментарий

  2. когда asp.net компилирует разметку, он использует параметр по умолчанию less constructor

  3. можно использовать любой тип коллекции, но если вы хотите использовать преимущества viewstate, ваш тип коллекции должен реализовывать интерфейс IStateManager (ниже я написал источник коллекции, который я создал для себя с помощью поддержка управления государством)

  4. Да, элемент управления может иметь несколько коллекций, просто добавить обязательные атрибуты, как показано ниже:

(я использовал один из моих кодов, пожалуйста, замените имена с нужным именем) , если вы хотите иметь в первую очередь, вы должны определить его свойство в своем контроле. себе представить, у нас есть контроль под названием CustomControl, который проходит контроль, как показано ниже:

[System.Web.UI.ParseChildrenAttribute(true)] 
[System.Web.UI.PersistChildrenAttribute(false)] 
public class CustomControl : Control{ 
    private GraphCollection m_graphs; 
    [Bindable(false)] 
    [Category("Appearance")] 
    [DefaultValue("")] 
    [Localizable(true)] 
    [PersistenceMode(PersistenceMode.InnerProperty)] 
    public GraphCollection Graphs 
    { 
     get 
     { 
      if (this.m_graphs == null) { 
       this.m_graphs = new GraphCollection(); 
       if (base.IsTrackingViewState) { 
        this.m_graphs.TrackViewState(); 
       } 
      } 
      return this.m_graphs; 
     } 
    } 
} 

, как вы можете видеть выше кода, CustomControl имеет поле с именем «m_graphs» с типом «GraphCollection», также имущество, которое обнажает это поле также, пожалуйста, обратите внимание на его атрибут PersistenceMode, который говорит в asp.net собственности «Графы» должны упорно, как InnerProperty

также, пожалуйста, обратите внимание на два атрибута, применяемых к классу CustomControl атрибут ParseChildrenAttribute говорит, что asp.net вложенная разметка, должны рассматриваться как свойства и атрибут PersistChildr enAttribute говорит asp.сеть, которая вложена вобще не дети контрольной

в финале, я привожу два исходные коды для государственных управляющих компонентов прежде всего GraphCollection, который простирается от StateManagedCollection (оба класса были написаны мной)

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.UI; 

namespace Farayan.Web.Core 
{ 
    public class StateManagedCollection<T> : IList, ICollection, IEnumerable, IEnumerable<T>, IStateManager 
     where T : class, IStateManager, new() 
    { 
     // Fields 
     private List<T> listItems = new List<T>(); 
     private bool marked = false; 
     private bool saveAll = false; 

     // Methods 
     public void Add(T item) 
     { 
      this.listItems.Add(item); 
      if (this.marked) { 
       //item.Dirty = true; 
      } 
     } 

     public void AddRange(T[] items) 
     { 
      if (items == null) { 
       throw new ArgumentNullException("items"); 
      } 
      foreach (T item in items) { 
       this.Add(item); 
      } 
     } 

     public void Clear() 
     { 
      this.listItems.Clear(); 
      if (this.marked) { 
       this.saveAll = true; 
      } 
     } 

     public bool Contains(T item) 
     { 
      return this.listItems.Contains(item); 
     } 

     public void CopyTo(Array array, int index) 
     { 
      this.listItems.CopyTo(array.Cast<T>().ToArray(), index); 
     } 

     public IEnumerator GetEnumerator() 
     { 
      return this.listItems.GetEnumerator(); 
     } 

     public int IndexOf(T item) 
     { 
      return this.listItems.IndexOf(item); 
     } 

     public void Insert(int index, T item) 
     { 
      this.listItems.Insert(index, item); 
      if (this.marked) { 
       this.saveAll = true; 
      } 
     } 

     public void LoadViewState(object state) 
     { 
      object[] states = state as object[]; 
      if (state == null || states.Length == 0) 
       return; 
      for (int i = 0; i < states.Length; i++) { 
       object itemState = states[i]; 
       if (i < Count) { 
        T day = (T)listItems[i]; 
        ((IStateManager)day).LoadViewState(itemState); 
       } else { 
        T day = new T(); 
        ((IStateManager)day).LoadViewState(itemState); 
        listItems.Add(day); 
       } 
      } 
     } 

     public void Remove(T item) 
     { 
      int index = this.IndexOf(item); 
      if (index >= 0) 
       this.RemoveAt(index); 
     } 

     public void RemoveAt(int index) 
     { 
      this.listItems.RemoveAt(index); 
      if (this.marked) { 
       this.saveAll = true; 
      } 
     } 

     public object SaveViewState() 
     { 
      List<object> state = new List<object>(Count); 
      foreach (T day in listItems) 
       state.Add(((IStateManager)day).SaveViewState()); 
      return state.ToArray(); 
     } 

     int IList.Add(object item) 
     { 
      T item2 = (T)item; 
      this.listItems.Add(item2); 
      return listItems.Count - 1; 
     } 

     bool IList.Contains(object item) 
     { 
      return this.Contains((T)item); 
     } 

     int IList.IndexOf(object item) 
     { 
      return this.IndexOf((T)item); 
     } 

     void IList.Insert(int index, object item) 
     { 
      this.Insert(index, (T)item); 
     } 

     void IList.Remove(object item) 
     { 
      this.Remove((T)item); 
     } 

     void IStateManager.LoadViewState(object state) 
     { 
      this.LoadViewState(state); 
     } 

     object IStateManager.SaveViewState() 
     { 
      return this.SaveViewState(); 
     } 

     void IStateManager.TrackViewState() 
     { 
      this.TrackViewState(); 
     } 

     public void TrackViewState() 
     { 
      this.marked = true; 
      for (int i = 0; i < this.Count; i++) { 
       ((IStateManager)this[i]).TrackViewState(); 
      } 
     } 

     // Properties 
     public int Capacity 
     { 
      get 
      { 
       return this.listItems.Capacity; 
      } 
      set 
      { 
       this.listItems.Capacity = value; 
      } 
     } 

     public int Count 
     { 
      get 
      { 
       return this.listItems.Count; 
      } 
     } 

     public bool IsReadOnly 
     { 
      get 
      { 
       return false; 
      } 
     } 

     public bool IsSynchronized 
     { 
      get 
      { 
       return false; 
      } 
     } 

     public T this[int index] 
     { 
      get 
      { 
       return (T)this.listItems[index]; 
      } 
     } 

     public object SyncRoot 
     { 
      get 
      { 
       return this; 
      } 
     } 

     bool IList.IsFixedSize 
     { 
      get 
      { 
       return false; 
      } 
     } 

     object IList.this[int index] 
     { 
      get 
      { 
       return this.listItems[index]; 
      } 
      set 
      { 
       this.listItems[index] = (T)value; 
      } 
     } 

     bool IStateManager.IsTrackingViewState 
     { 
      get 
      { 
       return this.marked; 
      } 
     } 

     #region IEnumerable<T> Members 

     IEnumerator<T> IEnumerable<T>.GetEnumerator() 
     { 
      return this.listItems.GetEnumerator(); 
     } 

     #endregion 

     #region IEnumerable Members 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return this.GetEnumerator(); 
     } 

     #endregion 
    } 
} 

и GraphCollection

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Farayan.Web.Core; 

namespace Farayan.Web.AmCharts 
{ 
    public class GraphCollection : StateManagedCollection<Graph> 
    { 
    } 
} 

и, наконец, Graph в нашем примере:

using System; 
using System.Linq; 
using System.Collections.ObjectModel; 
using System.Drawing; 
using System.Web.UI; 
using System.ComponentModel; 
using Farayan.Web.AmCharts; 
using System.Collections.Generic; 
using Farayan.Web.Controls; 
using System.Runtime; 
using Farayan.Web.Core; 

namespace Farayan.Web.AmCharts 
{ 
    public class Graph : StateManager 
    { 
     #region Colorize Property 
     [Browsable(true)] 
     [Localizable(false)] 
     [PersistenceMode(PersistenceMode.Attribute)] 
     [DefaultValue(false)] 
     public virtual bool Colorize 
     { 
      get { return ViewState["Colorize"] == null ? false : (bool)ViewState["Colorize"]; } 
      set { ViewState["Colorize"] = value; } 
     } 
     #endregion 

     //============================== 

     public override void LoadViewState(object state) 
     { 
      base.LoadViewState(state); 
     } 

     public override object SaveViewState() 
     { 
      return base.SaveViewState(); 
     } 
    } 
} 

вы можете заметить, что Graph extends StateManager класс

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Web.UI; 
using Farayan.Web.AmCharts; 

namespace Farayan.Web.AmCharts 
{ 
    public class StateManager : IStateManager 
    { 
     protected StateBag ViewState = new StateBag(); 

     #region IStateManager Members 

     public virtual bool IsTrackingViewState 
     { 
      get { return true; } 
     } 

     public virtual void LoadViewState(object state) 
     { 
      if (state != null) { 
       ArrayList arrayList = (ArrayList)state; 
       for (int i = 0; i < arrayList.Count; i += 2) { 
        string value = ((IndexedString)arrayList[i]).Value; 
        object value2 = arrayList[i + 1]; 
        ViewState.Add(value, value2); 
       } 
      } 
     } 

     public virtual object SaveViewState() 
     { 
      ArrayList arrayList = new ArrayList(); 
      if (this.ViewState.Count != 0) { 
       IDictionaryEnumerator enumerator = this.ViewState.GetEnumerator(); 
       while (enumerator.MoveNext()) { 
        StateItem stateItem = (StateItem)enumerator.Value; 
        //if (stateItem.IsDirty) { 
        if (arrayList == null) { 
         arrayList = new ArrayList(); 
        } 
        arrayList.Add(new IndexedString((string)enumerator.Key)); 
        arrayList.Add(stateItem.Value); 
        //} 
       } 
      } 
      return arrayList; 
     } 

     public virtual void TrackViewState() 
     { 

     } 

     #endregion 

     #region IStateManager Members 

     bool IStateManager.IsTrackingViewState 
     { 
      get { return this.IsTrackingViewState; } 
     } 

     void IStateManager.LoadViewState(object state) 
     { 
      this.LoadViewState(state); 
     } 

     object IStateManager.SaveViewState() 
     { 
      return this.SaveViewState(); 
     } 

     void IStateManager.TrackViewState() 
     { 
      this.TrackViewState(); 
     } 

     #endregion 
    } 
} 
Смежные вопросы