• 模板化数据绑定控件示例


    在以下示例中描述的 TemplatedList 控件是 System.Web.UI.DataList 控件的简化版本。该控件阐释以下概念。
    • 数据绑定,在开发模板化数据绑定控件中描述。

      DataSourceTemplatedList 的数据源。

      ItemTemplateTemplatedList 的模板属性。

      TemplatedListItemItemTemplate 的逻辑容器。TemplatedListItem 具有属性 DataItem,该属性绑定到 DataSource 的每一元素。

    • 事件冒泡,在事件冒泡中描述。

      TemplatedListItem 将命令事件从模板中的控件冒泡到 TemplatedListTemplatedList 将冒泡事件作为 ItemCommand 事件公开。TemplatedListCommandEventArgs 类包含该事件的数据。

    • 公开来自服务器控件中的样式中所描述控件的样式。

      TemplatedList 公开类型 System.Web.UI.WebControls.TableStyleItemStyleAlternatingItemStyleSelectedItemStyle 属性。

    • 使用 ViewState 自定义状态还原。

      TemplatedList 重写从 Control 继承的 SaveViewStateLoadViewState 方法以自定义其 Style 属性的还原。

    • 为设计时支持应用元数据属性。有关设计时属性的信息,请参见属性与设计时支持。在 DesignerAttribute 中指定的设计器 (CustomControls.Design.TemplatedListDesigner) 是在 Web 窗体模板数据绑定控件设计器示例中实现的。

    若要生成该示例,请参见服务器控件示例中的说明。

    [C#]
    // TemplatedList.cs.
    
    namespace CustomControls {
    
        using System;
        using System.ComponentModel;
        using System.ComponentModel.Design;
        using System.ComponentModel.Design.Serialization;
        using System.Collections;
        using System.Diagnostics;
        using System.Web.UI;
        using System.Web.UI.WebControls;
    
        [
        DefaultEvent("SelectedIndexChanged"),
        DefaultProperty("DataSource"),
        Designer("CustomControls.Design.TemplatedListDesigner, CustomControls.Design", typeof(IDesigner))
        ]
        public class TemplatedList : WebControl, INamingContainer {
    
    #region Statics and Constants
            private static readonly object EventSelectedIndexChanged = new object();
            private static readonly object EventItemCreated = new object();
            private static readonly object EventItemDataBound = new object();
            private static readonly object EventItemCommand = new object();
    #endregion
    
    #region Member variables
            private IEnumerable dataSource;
            private TableItemStyle itemStyle;
            private TableItemStyle alternatingItemStyle;
            private TableItemStyle selectedItemStyle;
            private ITemplate itemTemplate;
    #endregion
    
    #region Properties
            [
            Category("Style"),
            Description("The style to be applied to alternate items."),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
            NotifyParentProperty(true),
            PersistenceMode(PersistenceMode.InnerProperty),
            ]
            public virtual TableItemStyle AlternatingItemStyle {
                get {
                    if (alternatingItemStyle == null) {
                        alternatingItemStyle = new TableItemStyle();
                        if (IsTrackingViewState)
                            ((IStateManager)alternatingItemStyle).TrackViewState();
                    }
                    return alternatingItemStyle;
                }
            }
    
            [
            Bindable(true),
            Category("Appearance"),
            DefaultValue(-1),
            Description("The cell padding of the rendered table.")
            ]
            public virtual int CellPadding {
                get {
                    if (ControlStyleCreated == false) {
                        return -1;
                    }
                    return ((TableStyle)ControlStyle).CellPadding;
                }
                set {
                    ((TableStyle)ControlStyle).CellPadding = value;
                }
            }
    
            [
            Bindable(true),
            Category("Appearance"),
            DefaultValue(0),
            Description("The cell spacing of the rendered table.")
            ]
            public virtual int CellSpacing {
                get {
                    if (ControlStyleCreated == false) {
                        return 0;
                    }
                    return ((TableStyle)ControlStyle).CellSpacing;
                }
                set {
                    ((TableStyle)ControlStyle).CellSpacing = value;
                }
            }
    
            [
            Bindable(true),
            Category("Data"),
            DefaultValue(null),
            Description("The data source used to build up the control."),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
            ]
            public IEnumerable DataSource {
                get {
                    return dataSource;
                }
                set {
                    dataSource = value;
                }
            }
    
            [
            Bindable(true),
            Category("Appearance"),
            DefaultValue(GridLines.None),
            Description("The grid lines to be shown in the rendered table.")
            ]
            public virtual GridLines GridLines {
                get {
                    if (ControlStyleCreated == false) {
                        return GridLines.None;
                    }
                    return ((TableStyle)ControlStyle).GridLines;
                }
                set {
                    ((TableStyle)ControlStyle).GridLines = value;
                }
            }
    
            [
            Category("Style"),
            Description("The style to be applied to all items."),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
            NotifyParentProperty(true),
            PersistenceMode(PersistenceMode.InnerProperty),
            ]
            public virtual TableItemStyle ItemStyle {
                get {
                    if (itemStyle == null) {
                        itemStyle = new TableItemStyle();
                        if (IsTrackingViewState)
                            ((IStateManager)itemStyle).TrackViewState();
                    }
                    return itemStyle;
                }
            }
    
            [
            Browsable(false),
            DefaultValue(null),
            Description("The content to be shown in each item."),
            PersistenceMode(PersistenceMode.InnerProperty),
            TemplateContainer(typeof(TemplatedListItem))
            ]
            public virtual ITemplate ItemTemplate {
                get {
                    return itemTemplate;
                }
                set {
                    itemTemplate = value;
                }
            }
    
            [
            Bindable(true),
            DefaultValue(-1),
            Description("The index of the selected item.")
            ]
            public virtual int SelectedIndex {
                get {
                    object o = ViewState["SelectedIndex"];
                    if (o != null)
                        return(int)o;
                    return -1;
                }
                set {
                    if (value < -1) {
                        throw new ArgumentOutOfRangeException();
                    }
                    int oldSelectedIndex = SelectedIndex;
                    ViewState["SelectedIndex"] = value;
    
                    if (HasControls()) {
                        Table table = (Table)Controls[0];
                        TemplatedListItem item;
    
                        if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex)) {
                            item = (TemplatedListItem)table.Rows[oldSelectedIndex];
    
                            if (item.ItemType != ListItemType.EditItem) {
                                ListItemType itemType = ListItemType.Item;
                                if (oldSelectedIndex % 2 != 0)
                                    itemType = ListItemType.AlternatingItem;
                                item.SetItemType(itemType);
                            }
                        }
                        if ((value != -1) && (table.Rows.Count > value)) {
                            item = (TemplatedListItem)table.Rows[value];
                            item.SetItemType(ListItemType.SelectedItem);
                        }
                    }
                }
            }
    
            [
            Category("Style"),
            Description("The style to be applied to the selected item."),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
            NotifyParentProperty(true),
            PersistenceMode(PersistenceMode.InnerProperty),
            ]
            public virtual TableItemStyle SelectedItemStyle {
                get {
                    if (selectedItemStyle == null) {
                        selectedItemStyle = new TableItemStyle();
                        if (IsTrackingViewState)
                            ((IStateManager)selectedItemStyle).TrackViewState();
                    }
                    return selectedItemStyle;
                }
            }
    #endregion
    
    #region Events
            protected virtual void OnItemCommand(TemplatedListCommandEventArgs e) {
                TemplatedListCommandEventHandler onItemCommandHandler = (TemplatedListCommandEventHandler)Events[EventItemCommand];
                if (onItemCommandHandler != null) onItemCommandHandler(this, e);
            }
    
            protected virtual void OnItemCreated(TemplatedListItemEventArgs e) {
                TemplatedListItemEventHandler onItemCreatedHandler = (TemplatedListItemEventHandler)Events[EventItemCreated];
                if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
            }
    
            protected virtual void OnItemDataBound(TemplatedListItemEventArgs e) {
                TemplatedListItemEventHandler onItemDataBoundHandler = (TemplatedListItemEventHandler)Events[EventItemDataBound];
                if (onItemDataBoundHandler != null) onItemDataBoundHandler(this, e);
            }
    
            protected virtual void OnSelectedIndexChanged(EventArgs e) {
                EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
                if (handler != null) handler(this, e);
            }
    
            [
            Category("Action"),
            Description("Raised when a CommandEvent occurs within an item.")
            ]
            public event TemplatedListCommandEventHandler ItemCommand {
                add {
                    Events.AddHandler(EventItemCommand, value);
                }
                remove {
                    Events.RemoveHandler(EventItemCommand, value);
                }
            }
    
            [
            Category("Behavior"),
            Description("Raised when an item is created and is ready for customization.")
            ]
            public event TemplatedListItemEventHandler ItemCreated {
                add {
                    Events.AddHandler(EventItemCreated, value);
                }
                remove {
                    Events.RemoveHandler(EventItemCreated, value);
                }
            }
    
            [
            Category("Behavior"),
            Description("Raised when an item is data-bound.")
            ]
            public event TemplatedListItemEventHandler ItemDataBound {
                add {
                    Events.AddHandler(EventItemDataBound, value);
                }
                remove {
                    Events.RemoveHandler(EventItemDataBound, value);
                }
            }
    
            [
            Category("Action"),
            Description("Raised when the SelectedIndex property has changed.")
            ]
            public event EventHandler SelectedIndexChanged {
                add {
                    Events.AddHandler(EventSelectedIndexChanged, value);
                }
                remove {
                    Events.RemoveHandler(EventSelectedIndexChanged, value);
                }
            }
    #endregion
    
    #region Methods and Implementation
            protected override void CreateChildControls() {
                Controls.Clear();
    
                if (ViewState["ItemCount"] != null) {
                    // Create the control hierarchy using the view state, 
                    // not the data source.
                    CreateControlHierarchy(false);
                }
            }
    
            private void CreateControlHierarchy(bool useDataSource) {
                IEnumerable dataSource = null;
                int count = -1;
    
                if (useDataSource == false) {
                    // ViewState must have a non-null value for ItemCount because this is checked 
                    //  by CreateChildControls.
                    count = (int)ViewState["ItemCount"];
                    if (count != -1) {
                        dataSource = new DummyDataSource(count);
                    }
                }
                else {
                    dataSource = this.dataSource;
                }
    
                if (dataSource != null) {
                    Table table = new Table();
                    Controls.Add(table);
    
                    int selectedItemIndex = SelectedIndex;
                    int index = 0;
    
                    count = 0;
                    foreach (object dataItem in dataSource) {
                        ListItemType itemType = ListItemType.Item;
                        if (index == selectedItemIndex) {
                            itemType = ListItemType.SelectedItem;
                        }
                        else if (index % 2 != 0) {
                            itemType = ListItemType.AlternatingItem;
                        }
    
                        CreateItem(table, index, itemType, useDataSource, dataItem);
                        count++;
                        index++;
                    }
                }
    
                if (useDataSource) {
                    // Save the number of items contained for use in round trips.
                    ViewState["ItemCount"] = ((dataSource != null) ? count : -1);
                }
            }
    
            protected override Style CreateControlStyle() {
                // Since the TemplatedList control renders an HTML table, 
                // an instance of the TableStyle class is used as the control style.
    
                TableStyle style = new TableStyle(ViewState);
    
                // Set up default initial state.
                style.CellSpacing = 0;
    
                return style;
            }
    
            private TemplatedListItem CreateItem(Table table, int itemIndex, ListItemType itemType, bool dataBind, object dataItem) {
                TemplatedListItem item = new TemplatedListItem(itemIndex, itemType);
                TemplatedListItemEventArgs e = new TemplatedListItemEventArgs(item);
    
                if (itemTemplate != null) {
                    itemTemplate.InstantiateIn(item.Cells[0]);
                }
                if (dataBind) {
                    item.DataItem = dataItem;
                }
                OnItemCreated(e);
                table.Rows.Add(item);
    
                if (dataBind) {
                    item.DataBind();
                    OnItemDataBound(e);
    
                    item.DataItem = null;
                }
    
                return item;
            }
    
            public override void DataBind() {
                // Controls with a data-source property perform their custom data binding
                // by overriding DataBind.
    
                // Evaluate any data-binding expressions on the control itself.
                base.OnDataBinding(EventArgs.Empty);
    
                // Reset the control state.
                Controls.Clear();
                ClearChildViewState();
    
                //  Create the control hierarchy using the data source.
                CreateControlHierarchy(true);
                ChildControlsCreated = true;
    
                TrackViewState();
            }
    
            protected override void LoadViewState(object savedState) {
                // Customize state management to handle saving state of contained objects.
    
                if (savedState != null) {
                    object[] myState = (object[])savedState;
    
                    if (myState[0] != null)
                        base.LoadViewState(myState[0]);
                    if (myState[1] != null)
                        ((IStateManager)ItemStyle).LoadViewState(myState[1]);
                    if (myState[2] != null)
                        ((IStateManager)SelectedItemStyle).LoadViewState(myState[2]);
                    if (myState[3] != null)
                        ((IStateManager)AlternatingItemStyle).LoadViewState(myState[3]);
                }
            }
    
            protected override bool OnBubbleEvent(object source, EventArgs e) {
                // Handle events raised by children by overriding OnBubbleEvent.
    
                bool handled = false;
    
                if (e is TemplatedListCommandEventArgs) {
                    TemplatedListCommandEventArgs ce = (TemplatedListCommandEventArgs)e;
    
                    OnItemCommand(ce);
                    handled = true;
    
                    if (String.Compare(ce.CommandName, "Select", true) == 0) {
                        SelectedIndex = ce.Item.ItemIndex;
                        OnSelectedIndexChanged(EventArgs.Empty);
                    }
                }
    
                return handled;
            }
    
            private void PrepareControlHierarchy() {
                if (HasControls() == false) {
                    return;
                }
    
                Debug.Assert(Controls[0] is Table);
                Table table = (Table)Controls[0];
    
                table.CopyBaseAttributes(this);
                if (ControlStyleCreated) {
                    table.ApplyStyle(ControlStyle);
                }
    
                // The composite alternating item style; do just one
                // merge style on the actual item.
                Style altItemStyle = null;
                if (alternatingItemStyle != null) {
                    altItemStyle = new TableItemStyle();
                    altItemStyle.CopyFrom(itemStyle);
                    altItemStyle.CopyFrom(alternatingItemStyle);
                }
                else {
                    altItemStyle = itemStyle;
                }
    
                int rowCount = table.Rows.Count;
                for (int i = 0; i < rowCount; i++) {
                    TemplatedListItem item = (TemplatedListItem)table.Rows[i];
                    Style compositeStyle = null;
    
                    switch (item.ItemType) {
                        case ListItemType.Item:
                            compositeStyle = itemStyle;
                            break;
    
                        case ListItemType.AlternatingItem:
                            compositeStyle = altItemStyle;
                            break;
    
                        case ListItemType.SelectedItem: {
                            compositeStyle = new TableItemStyle();
    
                            if (item.ItemIndex % 2 != 0)
                                compositeStyle.CopyFrom(altItemStyle);
                            else
                                compositeStyle.CopyFrom(itemStyle);
                            compositeStyle.CopyFrom(selectedItemStyle);
                        }
                            break;
                    }
    
                    if (compositeStyle != null) {
                        item.MergeStyle(compositeStyle);
                    }
                }
            }
    
            protected override void Render(HtmlTextWriter writer) {
                // Apply styles to the control hierarchy
                // and then render it out.
    
                // Apply styles during render phase, so the user can change styles
                // after calling DataBind without the property changes ending
                // up in view state.
                PrepareControlHierarchy();
    
                RenderContents(writer);
            }
    
            protected override object SaveViewState() {
                // Customized state management to handle saving state of contained objects such as styles.
    
                object baseState = base.SaveViewState();
                object itemStyleState = (itemStyle != null) ? ((IStateManager)itemStyle).SaveViewState() : null;
                object selectedItemStyleState = (selectedItemStyle != null) ? ((IStateManager)selectedItemStyle).SaveViewState() : null;
                object alternatingItemStyleState = (alternatingItemStyle != null) ? ((IStateManager)alternatingItemStyle).SaveViewState() : null;
    
                object[] myState = new object[4];
                myState[0] = baseState;
                myState[1] = itemStyleState;
                myState[2] = selectedItemStyleState;
                myState[3] = alternatingItemStyleState;
    
                return myState;
            }
    
            protected override void TrackViewState() {
                // Customized state management to handle saving state of contained objects such as styles.
    
                base.TrackViewState();
    
                if (itemStyle != null)
                    ((IStateManager)itemStyle).TrackViewState();
                if (selectedItemStyle != null)
                    ((IStateManager)selectedItemStyle).TrackViewState();
                if (alternatingItemStyle != null)
                    ((IStateManager)alternatingItemStyle).TrackViewState();
            }
    #endregion
        }
    
    
        public class TemplatedListItem : TableRow, INamingContainer {
            private int itemIndex;
            private ListItemType itemType;
            private object dataItem;
    
            public TemplatedListItem(int itemIndex, ListItemType itemType) {
                this.itemIndex = itemIndex;
                this.itemType = itemType;
    
                Cells.Add(new TableCell());
            }
    
            public virtual object DataItem {
                get {
                    return dataItem;
                }
                set {
                    dataItem = value;
                }
            }
    
            public virtual int ItemIndex {
                get {
                    return itemIndex;
                }
            }
    
            public virtual ListItemType ItemType {
                get {
                    return itemType;
                }
            }
    
            protected override bool OnBubbleEvent(object source, EventArgs e) {
                if (e is CommandEventArgs) {
                    // Add the information about Item to CommandEvent.
    
                    TemplatedListCommandEventArgs args =
                        new TemplatedListCommandEventArgs(this, source, (CommandEventArgs)e);
    
                    RaiseBubbleEvent(this, args);
                    return true;
                }
                return false;
            }
    
            internal void SetItemType(ListItemType itemType) {
                this.itemType = itemType;
            }
        }
    
        public sealed class TemplatedListCommandEventArgs : CommandEventArgs {
    
            private TemplatedListItem item;
            private object commandSource;
    
            public TemplatedListCommandEventArgs(TemplatedListItem item, object commandSource, CommandEventArgs originalArgs) :
                base(originalArgs) {
                this.item = item;
                this.commandSource = commandSource;
            }
    
            public TemplatedListItem Item {
                get {
                    return item;
                }
            }
    
            public object CommandSource {
                get {
                    return commandSource;
                }
            }
        }
    
        public delegate void TemplatedListCommandEventHandler(object source, TemplatedListCommandEventArgs e);
    
        public sealed class TemplatedListItemEventArgs : EventArgs {
    
            private TemplatedListItem item;
    
            public TemplatedListItemEventArgs(TemplatedListItem item) {
                this.item = item;
            }
    
            public TemplatedListItem Item {
                get {
                    return item;
                }
            }
        }
    
        public delegate void TemplatedListItemEventHandler(object sender, TemplatedListItemEventArgs e);
    
        internal sealed class DummyDataSource : ICollection {
    
            private int dataItemCount;
    
            public DummyDataSource(int dataItemCount) {
                this.dataItemCount = dataItemCount;
            }
    
            public int Count {
                get {
                    return dataItemCount;
                }
            }
    
            public bool IsReadOnly {
                get {
                    return false;
                }
            }
    
            public bool IsSynchronized {
                get {
                    return false;
                }
            }
    
            public object SyncRoot {
                get {
                    return this;
                }
            }
    
            public void CopyTo(Array array, int index) {
                for (IEnumerator e = this.GetEnumerator(); e.MoveNext();)
                    array.SetValue(e.Current, index++);
            }
    
            public IEnumerator GetEnumerator() {
                return new DummyDataSourceEnumerator(dataItemCount);
            }
    
    
            private class DummyDataSourceEnumerator : IEnumerator {
    
                private int count;
                private int index;
    
                public DummyDataSourceEnumerator(int count) {
                    this.count = count;
                    this.index = -1;
                }
    
                public object Current {
                    get {
                        return null;
                    }
                }
    
                public bool MoveNext() {
                    index++;
                    return index < count;
                }
    
                public void Reset() {
                    this.index = -1;
                }
            }
        }
    }





    在页上使用数据绑定控件

    以下示例说明使用 TemplatedList 控件的 ASP.NET 页。

    [C#]
    <%@ Page language="C#" %>
    <%@ Register TagPrefix="custom" Namespace="CustomControls" Assembly="CustomControls"%>
    <html>
    <head>
      <title>Data-Bound Control Sample</title>
    </head>
    <body>
    <form runat="server">
    <h3>TemplatedList Control Sample</h3>
    <hr>
    <custom:TemplatedList runat="server" id="myList"
        Font-Name="Verdana" Font-Size="16pt"
        BorderColor="Gray" BorderWidth="1px"
        CellSpacing="0" CellPadding="2" GridLines="Both"
        onItemCreated="MyList_ItemCreated"
        onSelectedIndexChanged="MyList_SelectedIndexChanged">
      <ItemStyle ForeColor="Black" BackColor="#EEEEEE"/>
      <AlternatingItemStyle BackColor="#DCDCDC"/>
      <SelectedItemStyle ForeColor="White" BackColor="#000084"/>
      
      <ItemTemplate>
        <asp:Button runat="server" id="selectButton" CommandName="Select"
            Text="Select" ForeColor="Blue"></asp:Button>&nbsp;&nbsp;
        <asp:Label runat="server" Text='<%# Container.DataItem %>'/>
      </ItemTemplate>
    </custom:TemplatedList>
    <hr>
    <asp:Label runat="server" id="infoLabel"></asp:Label>
    <hr>
    </form>
    <script runat="server">
    
    private int selectedIndex = -1;
    
    private void LoadData() {
        ArrayList data = new ArrayList();
    
        for (int i = 0; i < 10; i++) {
            data.Add("Item " + i);
        }
    
        myList.DataSource = data;
        myList.DataBind();
    }
    
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        if (!IsPostBack) {
            LoadData();
        }
    }
    
    protected void MyList_ItemCreated(object sender, TemplatedListItemEventArgs e) {
        if (e.Item.ItemType == ListItemType.SelectedItem) {
            selectedIndex = e.Item.ItemIndex;
    
            Button selectButton = (Button)e.Item.FindControl("selectButton");
            selectButton.Enabled = false;
        }
    }
    
    protected void MyList_SelectedIndexChanged(object sender, EventArgs e) {
        if (selectedIndex != -1) {
            Control item = myList.Controls[0].Controls[selectedIndex];
            Button selectButton = (Button)item.FindControl("selectButton");
            selectButton.Enabled = true;
        }
    
        selectedIndex = myList.SelectedIndex;
        infoLabel.Text = "SelectedIndex: " + selectedIndex;
    
        if (selectedIndex != -1) {
            Control item = myList.Controls[0].Controls[selectedIndex];
            Button selectButton = (Button)item.FindControl("selectButton");
            selectButton.Enabled = false;
        }
    }
    </script>
    </body>
    </html>
    
  • 相关阅读:
    MySQL百万级数据量分页查询方法及其优化
    聊一聊二维码扫描登录原理
    在吗?认识一下JWT(JSON Web Token) ?
    怎样和领导汇报工作,更容易获得升职加薪?谈谈和领导汇报的艺术
    javascript sleep pause 实现
    google 根据地址得ip 并显示
    javascript 闭包
    javascript 对象 telecom
    javascript 对象
    google maker 标注
  • 原文地址:https://www.cnblogs.com/YrRoom/p/311582.html
Copyright © 2020-2023  润新知