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