2013-09-24 6 views
0

Je veux créer un contrôle serveur personnalisé qui ressemble à ceci:Soutenir les éléments imbriqués dans ASP.Net personnalisés contrôles serveur

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

MyControl est bien sûr mis en œuvre en tant que contrôle du serveur, mais je ne pas veulent MyItem est un contrôle enfant. Au contraire, ils devraient exister en tant que simples objets .Net. J'ai une classe appelée MyItem, et le contrôle a une propriété appelée Items, et lorsque les éléments MyItem sont déclarés dans le balisage, les objets doivent être instanciés et ajoutés à la collection.

Les tutoriels sur MSDN n'expliquent pas réellement comment cela se produit. Voir: http://msdn.microsoft.com/en-us/library/9txe1d4x.aspx

Je voudrais savoir:

  1. Comment est <cc:MyItem> mis en correspondance avec la classe MyItem? Est-ce que l'élément dans le balisage doit avoir le même nom que la classe de l'objet?
  2. Quel constructeur de MyItem est appelé lorsque MyItems est ajouté de manière déclarative, et quand?
  3. Quels types de collection suis-je autorisé à utiliser pour contenir des objets MyItem? Le lien ci-dessus utilise ArrayList, mais puis-je utiliser la liste fortement typée à la place?
  4. Est-il possible qu'un contrôle contienne plusieurs collections?

Répondre

0
  1. Il est si fréquent d'utiliser le nom de la classe pour le balisage, mais vous pouvez attribuer un autre nom si vous voulez, je n'expliquerai plus, si vous voulez s'il vous plaît commentaires

  2. lorsque asp.net compile le balisage, il utilise le constructeur par défaut moins le constructeur

  3. vous pouvez utiliser n'importe quel type de collection mais si vous voulez utiliser les avantages de viewstate votre type de collection doit implémenter l'interface IStateManager (ci-dessous j'ai écrit la source de collection que j'ai créée pour moi soutien à la gestion de l'État)

  4. Oui, votre contrôle peut avoir plusieurs collections, il suffit d'ajouter les attributs requis comme ci-dessous:

(j'ai utilisé un de mes codes, s'il vous plaît remplacer les noms avec votre nom de votre choix) si vous voulez avoir collection tout d'abord vous devez définir sa propriété dans votre contrôle. imaginer que nous avons un contrôle nommé CustomControl qui étend le contrôle comme ci-dessous:

[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; 
     } 
    } 
} 

comme vous pouvez le voir dans code ci-dessus, CustomControl a un champ avec le nom « m_graphs » avec le type de « GraphCollection », également une propriété qui expose ce domaine aussi s'il vous plaît s'il vous plaît prêter attention à son attribut PersistenceMode qui dit à la propriété de asp.net « Graphiques » doit persisté comme InnerProperty

également s'il vous plaît attention à deux attributs appliqués à la classe CustomControl attribut ParseChildrenAttribute dit que asp.net balisage imbriqué, doivent être traitées comme des propriétés et attributs PersistChildr enAttribute dit à asp.net qui nichait marges bénéficiaires ne sont pas les enfants de contrôle

à la finale, je vous apporte deux codes sources pour les composants de gestion de l'Etat avant tout GraphCollection qui va de StateManagedCollection (les deux classes a été écrit par moi)

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 
    } 
} 

et 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> 
    { 
    } 
} 

et enfin graphique dans notre exemple:

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(); 
     } 
    } 
} 

vous pouvez remarquer que Graph étend la classe 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 
    } 
} 
Questions connexes