自定义控件源码(转贴)

Posted on 2008-04-22 15:24  xiaolei1982  阅读(260)  评论(0)    收藏  举报
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;

namespace abcde
{
    
/// <summary>
    
/// 表示TemplatedList的项
    
/// </summary>

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


        
/// <summary>
        
/// 获取或设置TemplatedListItem对象关联的数据项。 
        
/// </summary>

        public virtual object DataItem
        
{
            
get
            
{
                
return dataItem;
            }

            
set
            
{
                dataItem 
= value;
            }

        }


        
/// <summary>
        
/// 项索引
        
/// </summary>

        public virtual int ItemIndex
        
{
            
get
            
{
                
return itemIndex;
            }

        }


        
/// <summary>
        
/// 项类型
        
/// </summary>

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


        
/// <summary>
        
/// 设置项类型
        
/// </summary>
        
/// <param name="itemType"></param>

        internal void SetItemType(ListItemType itemType)
        
{
            
this.itemType = itemType;
        }

    }

}


    
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;
    
using abcde;
namespace abcde
{

    [
    DefaultEvent(
"SelectedIndexChanged"),
    DefaultProperty(
"DataSource")
    ]
    
public class TemplatedList : WebControl, INamingContainer
    
{


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

 
        
private IEnumerable dataSource;
        
private TableItemStyle itemStyle;
        
private TableItemStyle alternatingItemStyle;
        
private TableItemStyle selectedItemStyle;
        
private ITemplate itemTemplate;
        

      

        [
        Category(
"Style"),
        Description(
"交替项样式"),
        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;
            }

        }



        [
        Category(
"Style"),
        Description(
"一般项样式"),
        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;
            }

        }


        [
         Category(
"Style"),
         Description(
"选中项样式"),
         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;
            }

        }




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

        }


        [
        Bindable(
true),
        Category(
"Data"),
        DefaultValue(
null),
        Description(
"数据源"),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        
public IEnumerable DataSource
        
{
            
get
            
{
                
return dataSource;
            }

            
set
            
{
                dataSource 
= value;
            }

        }



        [
        Browsable(
false),
        DefaultValue(
null),
        Description(
"项模板"),
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(
typeof(TemplatedListItem))
        ]
        
public virtual ITemplate ItemTemplate
        
{
            
get
            
{
                
return itemTemplate;
            }

            
set
            
{
                itemTemplate 
= value;
            }

        }



        [
        Bindable(
true),
        DefaultValue(
-1),
        Description(
"选中项索引,默认为-1")
        ]
        
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);
                    }

                }

            }

        }



        

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

        }

        


        
/// <summary>
        
/// 重写创建子控件
        
/// </summary>

        protected override void CreateChildControls()
        
{
            Controls.Clear();

            
if (ViewState["ItemCount"!= null)
            
{
                
//创建一个带或不带指定数据源的控件层次结构
                CreateControlHierarchy(false);
            }

        }


        
/// <summary>
        
/// 重写创建控件样式
        
/// </summary>
        
/// <returns></returns>

        protected override Style CreateControlStyle()
        
{


            TableStyle style 
= new TableStyle(ViewState);
            style.CellSpacing 
= 0;

            
return style;
        }


        
/// <summary>
        
/// 创建一个带或不带指定数据源的控件层次结构
        
/// </summary>
        
/// <param name="useDataSource">指示是否要使用指定的数据源</param>

        //注意:当第二次执行数据绑定时,会执行两遍
        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)
            
{
                
//保存项数量
                ViewState["ItemCount"= ((dataSource != null? count : -1);
            }

        }



        
//创建项
        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()
        
{

            
base.OnDataBinding(EventArgs.Empty);

            
//移除控件
            Controls.Clear();
            
//清除视图状态信息
            ClearChildViewState();

            
//创建一个带或不带指定数据源的控件层次结构
            CreateControlHierarchy(true);
            ChildControlsCreated 
= true;

            TrackViewState();
        }


        
//事件冒泡
        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;
                
//预定义触发Selected事件
                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[
0is 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 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 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();
        }
 
    }


    

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

    
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default10.aspx.cs" Inherits="Default10" %>
<%@ Register  Namespace="abcde" TagPrefix="aspDemo" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
    
<aspDemo:TemplatedList runat="server" id="myList1"
    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 ID="Label1" runat="server" Text='<%# Container.DataItem %>'></asp:Label>
  
</ItemTemplate>
</aspDemo:TemplatedList>
<hr>
<asp:Label runat="server" id="infoLabel"></asp:Label>
<hr>
    
</div>
    
</form>
</body>
</html>

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

    
    myList1.DataSource 
= data;
    myList1.DataBind();
    
}


protected override void OnLoad(EventArgs e) {
    
base.OnLoad(e);
    
if (!IsPostBack) {
        LoadData();
        
//myList1.SelectedIndex = 4;
    }

}


    
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 
= myList1.Controls[0].Controls[selectedIndex];
        Button selectButton 
= (Button)item.FindControl("selectButton");
        selectButton.Enabled 
= true;
    }


    selectedIndex 
= myList1.SelectedIndex;
    infoLabel.Text 
= "SelectedIndex: " + selectedIndex;

    
if (selectedIndex != -1{
        Control item 
= myList1.Controls[0].Controls[selectedIndex];
        Button selectButton 
= (Button)item.FindControl("selectButton");
        selectButton.Enabled 
= false;
    }

   
}

</script>
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;

namespace abcde
{
    
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;
            }

        }

    }

}

博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3