Charles要求的User Control,例子如下:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Xml;
using BOLibrary.Code.Common;
using BOLibrary.Controls.Core.Buttons;
using BOLibrary.Controls.Core.Collctions;
using BOLibrary.Controls.Core.Columns;
using BOLibrary.Controls.Core.Keys;
using BOLibrary.Controls.Core.Fields;
using BOLibrary.Controls.Core.Interface;
namespace BOLibrary.Controls.Custom
{
[ToolboxData("<{0}:CompositeView runat=server></{0}:CompositeView>")]
public class CompositeView : ControlBase, IPostBackDataHandler, IPostBackEventHandler
{
public delegate void ButtonValidateDelegate(ButtonBase button);
public event ButtonValidateDelegate ButtonValidate;
public delegate void ColumnsValidateDelegate(ColumnCollection columns);
public event ColumnsValidateDelegate ColumsValidate;
private string action;
private ButtonCollection buttonContainer = new ButtonCollection();
private NameValueCollection checkBoxes = new NameValueCollection();
private NameValueCollection hides = new NameValueCollection();
private IdCollectionKey collectionKey;
private ColumnCollection columnContainer = new ColumnCollection();
private List<KeyBase> columnKeyList = new List<KeyBase>();
private string cssClass = "CompositeView";
private List<string> displayList = new List<string>();
private bool hasChangedSortIndex = false;
private bool hasCheckBox = true;
private List<Dictionary<string, object>> items;
private string selectedIds;
public override string ControlCssClass
{
get { return this.cssClass; }
set { this.cssClass = value; }
}
public bool HasCheckBox
{
get { return hasCheckBox; }
set { hasCheckBox = value; }
}
private bool _save;
public bool Save
{
get { return _save; }
set { _save = value; }
}
private Dictionary<string, string> _hiddata;
public Dictionary<string, string> HidData
{
get { return _hiddata; }
set { _hiddata = value; }
}
public List<Dictionary<string, object>> Items
{
get { return items; }
set { items = value; }
}
public int TotalRows
{
get
{
return int.Parse(this.items[this.items.Count - 1]["TotalRows"].ToString());
}
}
public void AddDisplayKey(string key)
{
if (!this.displayList.Contains(key))
this.displayList.Add(key);
}
#region Initialize Control
protected override void InitializeControl()
{
XmlElement configure = GetConfigureElement();
XmlElement columnsElement = configure["Columns"];
if (columnsElement == null)
throw new Exception("CompositeView needs Columns definition with at least one column node!");
if (columnsElement.HasAttribute("checkbox"))
this.hasCheckBox = columnsElement.Attributes["checkbox"].Value.Equals("true");
if (columnsElement.HasAttribute("collectionKey"))
{
collectionKey = new IdCollectionKey();
collectionKey.Key = columnsElement.Attributes["collectionKey"].Value;
collectionKey.GetIdCollection(this.idCollection);
}
Assembly assembly = Assembly.GetExecutingAssembly();
BasePage basePage = (BasePage)Page;
columnContainer.Clear();
displayList.Clear();
foreach (XmlNode columnNode in columnsElement)
{
#region Create Column object
string classTypeStr = columnNode["Type"].InnerText;
Type classType = assembly.GetType(classTypeStr);
ColumnBase classInstance = (ColumnBase)Activator.CreateInstance(classType);
classInstance.Text = columnNode["Text"].InnerText;
classInstance.IdCollection = this.idCollection;
classInstance.UniqueID = this.UniqueID;
classInstance.Server = Page.Server;
if (columnNode.Attributes["width"] != null)
classInstance.Width = columnNode.Attributes["width"].Value;
if (columnNode.Attributes["sort"] != null)
classInstance.HasSorting = columnNode.Attributes["sort"].Value.Equals("true");
if (columnNode.Attributes["group"] != null)
classInstance.Group = columnNode.Attributes["group"].Value;
if (columnNode.Attributes["display"] != null)
classInstance.DisplayKey = columnNode.Attributes["display"].Value;
#region Fill Form filter
XmlElement FillFormElement = columnNode["FillForm"];
if (FillFormElement != null)
{
if (FillFormElement.HasAttribute("formid"))
classInstance.FormId = FillFormElement.Attributes["formid"].Value;
classInstance.FillForm = FillFormElement["Field"].InnerText;
classInstance.FillFormJS = FillFormElement["Script"].InnerText;
}
#endregion
#region Access Right
XmlElement AccessRightElement = columnNode["AccessRight"];
if (AccessRightElement != null)
{
string sectionId = AccessRightElement["Section"].InnerText;
string ruleId = AccessRightElement["Rule"].InnerText;
if (!basePage.Authentication(sectionId, ruleId))
classInstance.Disabled = true;
}
#endregion
// All collection references should be assigned to the column instance
// before initialization.
classInstance.Initialize(columnNode);
#region IButtonAction Interface
if (classInstance is IButtonAction)
{
IButtonAction iba = classInstance as IButtonAction;
iba.Script = Page.ClientScript.GetPostBackEventReference(this, iba.Action);
}
#endregion
columnContainer.Add(classInstance);
#endregion
}
#region Buttons Initialization
XmlElement buttonElement = configure["Buttons"];
if (buttonElement != null)
{
buttonContainer.Clear();
foreach (XmlNode buttonNode in buttonElement)
{
ButtonBase button = null;
if (buttonNode["Type"] == null)
button = new PostBackButton();
else
{
string buttonTypeStr = buttonNode["Type"].InnerText;
Type buttonType = assembly.GetType(buttonTypeStr);
button = (ButtonBase)Activator.CreateInstance(buttonType);
}
if (buttonNode.Attributes["display"] != null)
button.DisplayTable = buttonNode.Attributes["display"].Value;
#region Access Right
XmlElement AccessRightNode = buttonNode["AccessRight"];
if (AccessRightNode != null)
{
string sectionId = AccessRightNode["Section"].InnerText;
string ruleId = AccessRightNode["Rule"].InnerText;
if (!basePage.Authentication(sectionId, ruleId))
button.Disabled = true;
}
#endregion
button.Text = buttonNode["Text"].InnerText;
button.Items = this.items;
button.UniqueID = this.UniqueID;
button.IdCollection = this.idCollection;
button.Initialize(buttonNode);
#region IButtonAction Interface
XmlElement confirmElement = buttonNode["Confirm"];
string confirmText = string.Empty;
if (confirmElement != null)
{
confirmText = "if(confirm('" + confirmElement["Text"].InnerText + "'))";
}
if (button is IButtonAction)
{
IButtonAction iba = button as IButtonAction;
iba.Script = confirmText+ Page.ClientScript.GetPostBackEventReference(this, iba.Action);
}
#endregion
buttonContainer.Add(button);
}
}
#endregion
#region Column Keys Initialization
XmlElement columnKeysElement = configure["ColumnKeys"];
if (columnKeysElement != null)
{
this.columnKeyList.Clear();
foreach (XmlNode columnKeysNode in columnKeysElement.ChildNodes)
{
KeyBase ckKey = null;
XmlElement ckType = columnKeysNode["Type"];
if (ckType != null)
ckKey = KeyBase.GetKeyInstance(ckType.InnerText);
else
ckKey = new IdKey();
ckKey.Key = columnKeysNode["Name"].InnerText;
if (ckKey is ISelfInitialize)
((ISelfInitialize)ckKey).SelfInitialize(columnKeysNode);
this.columnKeyList.Add(ckKey);
}
}
#endregion
}
#endregion
#region Render Control
private void RenderButtons(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class, "ButtonPanel");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
#region Has CheckBox
if (this.hasCheckBox)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class, "CheckBox");
writer.RenderBeginTag(HtmlTextWriterTag.Span);
writer.AddAttribute(HtmlTextWriterAttribute.Type, "checkbox");
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "OnCheckAll(this,'" + this.UniqueID + "_Items')");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag();
writer.RenderEndTag();
}
#endregion
foreach (ButtonBase button in buttonContainer)
{
if (!string.IsNullOrEmpty(button.DisplayTable))
{
string[] ids = button.DisplayTable.Split(new char[] { '@' });
if (idCollection[ids[0]] != null)
{
if (!idCollection[ids[0]].Equals(ids[1]))
continue;
}
}
if (ButtonValidate != null)
ButtonValidate(button);
if(!button.Disabled)
button.RenderControl(writer);
}
writer.RenderEndTag();
}
protected override void RenderContents(HtmlTextWriter writer)
{
RenderButtons(writer);
RenderItems(writer);
RenderButtons(writer);
}
private void RenderItems(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Table);
#region Render Header Columns
writer.AddAttribute(HtmlTextWriterAttribute.Class, "Header");
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
// Balance the checkbox cell in the item rows
if (this.hasCheckBox)
{
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.RenderEndTag();
}
if (ColumsValidate != null)
ColumsValidate(this.columnContainer);
List<int> NotShowIndex = new List<int>();
int index = 0;
foreach (ColumnBase column in this.columnContainer)
{
column.OnPreRender(this.displayList);
if (column.IsShowColumn(this.idCollection["Table"]) && !column.Disabled)
{
if (column.HasSorting)
{
string sortIndex = string.Empty;
if (ViewState[this.UniqueID + "_sortIndex"] != null)
sortIndex = (string)ViewState[this.UniqueID + "_sortIndex"];
string sortScript = Page.ClientScript.GetPostBackEventReference(this, "sortIndex@" + column.KeyName);
string SortCSS = "SortColumn";
if (!string.IsNullOrEmpty(sortIndex) && column.KeyName.Equals(sortIndex))
SortCSS += " Sort" + ViewState[this.UniqueID + "_sortType"].ToString();
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, sortScript);
writer.AddAttribute(HtmlTextWriterAttribute.Class, SortCSS);
// Still Have Authenication Problems in Firefox
/*if (SortCSS.Contains("Sortasc"))
writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, "url(/Images/Common/ArrowAsc.png)");
if (SortCSS.Contains("Sortdes"))
writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, "url(/Images/Common/ArrowDes.png)");*/
}
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(column.Text);
writer.RenderEndTag();
}
else
NotShowIndex.Add(index);
index++;
}
writer.RenderEndTag();
#endregion
if (this.items == null)
goto EndOfRender;
#region Render Items Content
// Ignore the last row, since it stores the total number of records only.
for (int i = 0; i < this.items.Count - 1; i++)
{
Dictionary<string, object> item = this.items[i];
if (i % 2 != 0)
writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, "#fff2df");
else
writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, "#ffffff");
writer.AddAttribute("onmouseout", "out(this)");
writer.AddAttribute("onmouseover", "over(this)");
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
string data = "";
string hidid = "";
if (this.hasCheckBox)
{
writer.RenderBeginTag(HtmlTextWriterTag.Td);
string CheckBoxValue = string.Empty;
if (this.columnKeyList.Count > 0)
{
foreach (KeyBase columnKey in this.columnKeyList)
{
if (!string.IsNullOrEmpty(CheckBoxValue))
CheckBoxValue += "%%";
CheckBoxValue += columnKey.GetValue(item);
}
}
else
CheckBoxValue = this.collectionKey.GetValue(item);
writer.AddAttribute(HtmlTextWriterAttribute.Value, CheckBoxValue);
RenderCheckBox(writer, this.UniqueID + "_Items");
writer.RenderEndTag();
if (Save)
{
data += CheckBoxValue + ",";
hidid = CheckBoxValue;
}
}
foreach (ColumnBase column in this.columnContainer)
{
column.OnPreRender(this.displayList);
if (column.IsShowColumn(this.idCollection["Table"]) && !column.Disabled)
{
//if (i % 2 != 0)
//writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, "#fff2df");
if (!string.IsNullOrEmpty(column.Width))
writer.AddAttribute(HtmlTextWriterAttribute.Width, column.Width);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
column.RenderControl(writer, item);
writer.RenderEndTag();
if (Save)
{
try
{
data += item[column.KeyName].ToString() + ",";
}
catch
{
data += ",";
}
}
}
}
if (Save)
{
writer.RenderBeginTag(HtmlTextWriterTag.Td);
HtmlInputHidden hid = new HtmlInputHidden();
hid.Value = data.Substring(0, data.Length - 1);
hid.ID = this.UniqueID+ "_hid_" + hidid;
hid.RenderControl(writer);
writer.RenderEndTag();
}
writer.RenderEndTag();
}
#endregion
EndOfRender:
writer.RenderEndTag();
}
#endregion
#region Events
public event EventHandler ButtonTriggerEvent;
public event EventHandler ItemTriggerEvent;
#endregion
#region IPostBackDataHandler Members
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
this.selectedIds = this.action = string.Empty;
this.checkBoxes.Clear();
this.hides.Clear();
if (Save)
HidData = new Dictionary<string, string>();
foreach (string key in postCollection.Keys)
{
if (key.Equals(this.UniqueID + "_Items"))
{
this.selectedIds = postCollection[key];
this.action = postCollection["__EVENTARGUMENT"];
string[] idList = this.selectedIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < idList.Length; i++)
{
string checkbox = (string)postCollection[this.UniqueID + "_" + idList[i] + "_CBColumn"];
if (!string.IsNullOrEmpty(checkbox))
{
this.checkBoxes.Add(idList[i], checkbox);
}
string hiddata = (string)postCollection[this.UniqueID + "_" + idList[i] + "_HidData"];
if (!string.IsNullOrEmpty(hiddata))
{
this.hides.Add(idList[i], hiddata);
}
//if (Save)
//{
// string hid = (string)postCollection[this.UniqueID + "_hid_" + idList[i]];
// HidData.Add(idList[i], hid);
//}
}
}
if (key.Contains(this.UniqueID + "_hid_"))
{
if (Save)
{
string hid = (string)postCollection[key];
HidData.Add(key.Substring(key.LastIndexOf("_") + 1, key.Length - key.LastIndexOf("_") - 1), hid);
}
}
}
string sortKey = this.UniqueID + "_sortIndex";
if (!string.IsNullOrEmpty(postCollection[sortKey]))
{
ViewState[sortKey] = postCollection[sortKey];
ViewState[this.UniqueID + "_sortType"] = postCollection[this.UniqueID + "_sortType"];
}
return !string.IsNullOrEmpty(this.selectedIds);
}
public void RaisePostDataChangedEvent()
{
if (this.ButtonTriggerEvent != null)
{
CompositeViewEventArgs args = new CompositeViewEventArgs();
args.Action = this.action;
args.ItemId = this.selectedIds;
args.CheckBoxes = this.checkBoxes;
args.HidData = HidData;
args.Hides = this.hides;
this.ButtonTriggerEvent(this, args);
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Page != null)
Page.RegisterRequiresPostBack(this);
if (Page.ClientScript.IsClientScriptIncludeRegistered("BOLibrary") == false)
Page.ClientScript.RegisterClientScriptInclude("BOLibrary",
Page.ClientScript.GetWebResourceUrl(this.GetType(), "BOLibrary.JS.BOLibrary.js"));
if (Page.ClientScript.IsClientScriptIncludeRegistered("Controls") == false)
Page.ClientScript.RegisterClientScriptInclude("Controls",
Page.ClientScript.GetWebResourceUrl(this.GetType(), "BOLibrary.JS.Controls.js"));
if (!Page.ClientScript.IsClientScriptBlockRegistered("Controls.css"))
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Controls.css", "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + Page.ClientScript.GetWebResourceUrl(this.GetType(), "BOLibrary.CSS.Controls.css") + "\" />");
if (!Page.ClientScript.IsClientScriptBlockRegistered("CompositeControls.css"))
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CompositeControls.css", "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + Page.ClientScript.GetWebResourceUrl(this.GetType(), "BOLibrary.CSS.CompositeControls.css") + "\" />");
}
#endregion
#region IPostBackEventHandler Members
public void RaisePostBackEvent(string eventArgument)
{
if (!string.IsNullOrEmpty(eventArgument))
{
if (this.ItemTriggerEvent != null)
{
string[] param = eventArgument.Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries);
CompositeViewEventArgs args = new CompositeViewEventArgs();
args.Action = param[0];
if (param.Length > 1)
args.ItemId = param[1];
if (eventArgument.Contains("sortIndex@"))
{
args.Action = "Sort";
string sortKey = this.UniqueID + "_sortType";
string sortIndex = eventArgument.Split(new char[]{'@'}, StringSplitOptions.RemoveEmptyEntries)[1];
if (ViewState[sortKey] != null)
{
switch ((string)ViewState[sortKey])
{
case "asc":
ViewState[sortKey] = args.SortType = "des";
break;
case "des":
ViewState[sortKey] = args.SortType = string.Empty;
break;
default:
ViewState[sortKey] = args.SortType = "asc";
break;
}
}
else
{
args.SortType = "asc";
ViewState[sortKey] = "asc";
}
if (ViewState[this.UniqueID + "_sortIndex"] != null)
{
if (!ViewState[this.UniqueID + "_sortIndex"].Equals(sortIndex))
{
ViewState[sortKey] = "asc";
args.SortType = "asc";
}
}
ViewState[this.UniqueID + "_sortIndex"] = sortIndex;
args.SortIndex = sortIndex;
}
if (Save)
{
args.HidData = HidData;
}
this.ItemTriggerEvent(this, args);
}
}
}
#endregion
}
}