【问题标题】:How do I make a control with a child control collection in ASP.Net如何在 ASP.Net 中使用子控件集合制作控件
【发布时间】:2011-12-11 03:11:06
【问题描述】:

我正在尝试为 asp.net 开发一个自定义控件,该控件将具有以下标记:

<bk:ControlMenu ID="cmTest" runat="server" Width="400px">               
    <Items>
        <asp:Textbox>
        <asp:Checkbox>
        [ List of controls... ]
    </Items>
</bk:ControlMenu>

当我开发我的控件时,什么样的属性允许我这样做? (项目集合是有问题的部分)。

【问题讨论】:

    标签: c# asp.net collections controls custom-controls


    【解决方案1】:

    您不能在标准 Web 用户控件中包含嵌套元素。您需要开发一个自定义服务器控件来实现这一点。要在自定义服务器控件中允许嵌套元素,您需要使用PersistenceMode 属性并将其设置为InnerProperty

    /// <summary>
    /// Gets the columns collection.
    /// </summary>
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [PersistenceMode(PersistenceMode.InnerProperty)]
    public ItemCollection Items
    {
        get
        {
            if (itemCollection == null)
            {
                if (itemArrayList == null)
                {
                    this.EnsureChildControls();
                    if (itemArrayList == null)
                        itemArrayList = new ArrayList();
                }
                itemCollection = new ItemCollection(itemArrayList);
            }
            return itemCollection;
        }
    }
    

    这是我创建的控件的示例:

    ScheduleGrid 控件

    /// <summary>
    /// Gets the columns collection.
    /// </summary>
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [PersistenceMode(PersistenceMode.InnerProperty)]
    public ScheduleGridColumnCollection Columns
    {
        get
        {
            if (scheduleColumnsCollection == null)
            {
                if (scheduleColumnsArrayList == null)
                {
                    this.EnsureChildControls();
                    if (scheduleColumnsArrayList == null)
                        scheduleColumnsArrayList = new ArrayList();
                }
                scheduleColumnsCollection = new ScheduleGridColumnCollection(scheduleColumnsArrayList);
            }
            return scheduleColumnsCollection;
        }
    }
    

    ScheduleGridColumn 类

    #region schedule column
    
    [PersistChildren(true)]
    public sealed class ScheduleGridColumn : DataGridColumn, INamingContainer
    {
        #region private member variables
    
        private bool editModeEnabled;
        private bool aggregateColumn;        
    
        private string uniqueName;
        private string dataFieldName;
        private string aggregateKey;
        private string dataFormatString;
    
        private ITemplate editTemplate = null;
    
        #endregion
    
        #region constructor
    
        /// <summary>
        /// Initializes the GridColumn object using default values.
        /// </summary>
        public ScheduleGridColumn()
        {
            //initialize other fields to defaults
            dataFieldName = String.Empty;
            dataFormatString = String.Empty;
            uniqueName = String.Empty;
    
            //disable edit mode by default
            editModeEnabled = false;
        }
    
        #endregion
    
        #region properties
    
        /// <summary>
        /// Gets or sets the edit template.
        /// </summary>      
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateInstance(TemplateInstance.Single)]
        public ITemplate EditTemplate
        {
            get
            {
                return editTemplate;
            }
            set
            {
                editTemplate = value;
            }
        }
    
        /// <summary>
        /// Gets or sets the unique name.
        /// </summary>
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string UniqueName
        {
            get
            {
                return uniqueName;
            }
            set
            {
                uniqueName = value;
            }
        }
    
        /// <summary>
        /// Gets or sets the name of the data field.
        /// </summary>
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string DataField
        {
            get
            {
                return dataFieldName;
            }
            set
            {
                dataFieldName = value;
            }
        }
    
        /// <summary>
        /// Gets or sets the format string used to format the data.
        /// </summary>
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string DataFormatString
        {
            get
            {
                return dataFormatString;
            }
            set
            {
                dataFormatString = value;
            }
        }
    
        /// <summary>
        /// Gets or sets a value indicating whether the item 
        /// is in edit mode.
        /// </summary>
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public bool EditModeEnabled
        {
            get
            {
                return editModeEnabled;
            }
            set
            {
                editModeEnabled = value;
            }
        }
    
        /// <summary>
        /// Gets or sets a value indicating whether the item should be aggregated.
        /// </summary>
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public bool AggregateColumn
        {
            get
            {
                return aggregateColumn;
            }
            set
            {
                aggregateColumn = value;
            }
        }
    
        /// <summary>
        /// Gets or sets the aggregate key.
        /// </summary>
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string AggregateKey
        {
            get
            {
                return aggregateKey;
            }
            set
            {
                aggregateKey = value;
            }
        }
    
        #endregion
    }
    
    #endregion
    

    ScheduleGridColumnCollection 类

    #region schedule column collection
    
    [PersistChildren(true)]
    public sealed class ScheduleGridColumnCollection : ICollection
    {
        #region member variables
    
        private ArrayList ItemArray;
        private string columnGroupTitle;
    
        #endregion
    
        #region constructors
    
        public ScheduleGridColumnCollection(ArrayList items)
        {
            ItemArray = items;
        }
    
        #endregion
    
        #region methods
    
        /// <summary>
        /// Finds the column corresponding to the data field.
        /// </summary>
        /// <param name="DataFieldName"></param>
        /// <returns></returns>
        public ScheduleGridColumn FindColumnDataField(string dataFieldName)
        {
            ScheduleGridColumn column = new ScheduleGridColumn();
            foreach (ScheduleGridColumn item in ItemArray.Cast<ScheduleGridColumn>())
            {
                if (item.DataField == dataFieldName)
                {
                    column = item;
                    break;
                }
            }
            return column;
        }
    
        public bool ContainsColumnWithDataField(string dataFieldName)
        {
            foreach (ScheduleGridColumn item in ItemArray.Cast<ScheduleGridColumn>())
                if (item.DataField == dataFieldName)
                    return true;
            return false;
        }
    
        /// <summary>
        /// Adds an item to the collection.
        /// </summary>
        /// <param name="item"></param>
        public void Add(ScheduleGridColumn item)
        {
            ItemArray.Add(item);
        }
    
        public void AddRange(ScheduleGridColumnCollection itemCollection)
        {
            foreach (ScheduleGridColumn item in itemCollection)
                ItemArray.Add(item);
        }
    
        /// <summary>
        /// Clears all items from the collection.
        /// </summary>
        public void Clear()
        {
            ItemArray.Clear();
        }
    
        /// <summary>
        /// Returns the enumerated equivalent of the collection.
        /// </summary>
        /// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            return ItemArray.GetEnumerator();
        }
    
        /// <summary>
        /// Copies the collection to the array parameter.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        public void CopyTo(Array array, int index)
        {
            ItemArray.CopyTo(array, index);
        }  
    
        #endregion
    
        #region properties
    
        /// <summary>
        /// Gets the schedule column located at the specified index.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ScheduleGridColumn this[int index]
        {
            get
            {
                return (ScheduleGridColumn)ItemArray[index];
            }
        }
    
        /// <summary>
        /// Gets a schedule column from the collection based on a unique name.
        /// </summary>
        /// <param name="uniqueName"></param>
        /// <returns></returns>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ScheduleGridColumn this[string uniqueName]
        {
            get
            {
                ScheduleGridColumn dataColumn = null;
                foreach (object item in ItemArray)
                    if (((ScheduleGridColumn)item).UniqueName == uniqueName)
                        dataColumn = (ScheduleGridColumn)item;
                return dataColumn;
            }
        }
    
        /// <summary>
        /// Gets the total number of items in the collection.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int Count
        {
            get
            {
                return ItemArray.Count;
            }
        }
    
        /// <summary>
        /// Gets a value indicating whether the collection is read only.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }
    
        /// <summary>
        /// Gets a value indicating whether the collection is synchronized.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsSynchronized
        {
            get
            {
                return false;
            }
        }
    
        /// <summary>
        /// Gets the sync root object.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object SyncRoot
        {
            get
            {
                return this;
            }
        }
    
        /// <summary>
        /// Gets or sets the column group title.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Browsable(true)]
        public string ColumnGroupTitle
        {
            get
            {
                return columnGroupTitle;
            }
            set
            {
                columnGroupTitle = value;
            }
        }
    
        #endregion
    }
    
    #endregion
    

    【讨论】:

    • Web 用户控制是指 .ascx 文件?这是一个扩展 System.Web.UI.WebControls.WebControl 的自定义类。它会为此工作吗?
    • 是的,它应该适用于继承自 WebControl 类的自定义控件。
    • 您是否有理由使用 ItemCollection 而不是 ControlCollection?
    • ItemCollection 继承自 ICollection,集合中的每个元素都继承自 DataGridColumn 类。
    • 我相信这将是我的最后一点澄清,但 scheduleColumnsArrayList 来自哪里?
    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 2010-12-07
    • 2011-04-25
    • 2011-01-27
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    • 2012-04-16
    相关资源
    最近更新 更多