ASP.NET Tutorial/Custom Controls/WebControl
Содержание
- 1 A control that inherits from the WebControl class.
- 2 Applying Design-Time Attributes to a Control
- 3 contains the custom pager control.
- 4 Creating a Container ControlDesigner
- 5 Displaying a table of HTML colors.
- 6 File: DropShadow.cs
- 7 Handling Postback Events
- 8 Processing Postback Data and Events
- 9 Specifying the Containing WebControl Tag
- 10 Supporting Control State
- 11 Using a ControlBuilder
- 12 Using Postback Options
- 13 View State and Control State
- 14 Working with Control Property Collections
- 15 You can add your own Smart Tasks to a custom control by inheriting a new class from the base DesignerActionList class.
- 16 Your own data binding control
- 17 <%# Container.Title %>
A control that inherits from the WebControl class.
<source lang="csharp">
using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class FullyRenderedWebControl : WebControl { private string _Text; public string Text { get { return _Text; } set { _Text = value; } } protected override void RenderContents(HtmlTextWriter writer) { writer.Write(_Text); } }
}
File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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 id="Head1" runat="server">
<title>Show Fully Rendered WebControl</title>
</head> <body>
<form id="form1" runat="server">
<custom:FullyRenderedWebControl ID="FullyrenderedWebControl1" Text="Hello World" BackColor="Yellow" BorderStyle="Dashed" Font-Size="32px" Runat="Server" />
</form>
</body> </html></source>
Applying Design-Time Attributes to a Control
<source lang="csharp">
File: ProductView.cs using System; using System.Web.UI; using System.Web.UI.WebControls; using System.ruponentModel; namespace myControls {
[DefaultProperty("Title")] public class ProductView : WebControl { private string _title = "Product Title"; private string _description = "Product Description"; [Category("Product")] [Description("Product Title")] public string Title { get { return _title; } set { _title = value; } } [Category("Product")] [Description("Product Description")] public string Description { get { return _description; } set { _description = value; } }
protected override void RenderContents(HtmlTextWriter writer) { writer.RenderBeginTag(HtmlTextWriterTag.H1); writer.Write(_title); writer.RenderEndTag(); writer.Write(_description); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } } }
} File: ShowProductView.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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 id="Head1" runat="server">
<title>Show ProductView</title>
</head> <body>
<form id="form1" runat="server">
<custom:ProductView id="ProductView1" Runat="server" />
</form>
</body> </html></source>
contains the custom pager control.
<source lang="csharp">
using System; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class Pager : WebControl, IPostBackEventHandler { string _controlToPage; public string ControlToPage { get { return _controlToPage; } set { _controlToPage = value; } } protected override void RenderContents(HtmlTextWriter writer) { GridView grid = GetControlToPage(); for (int i = 0; i < grid.PageCount; i++) { string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, i.ToString()); writer.Write("["); if (i == grid.PageIndex) writer.AddStyleAttribute(HtmlTextWriterStyle.FontWeight, "bold"); writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.Write("{0}", i + 1); writer.RenderEndTag(); writer.Write("] "); } } private GridView GetControlToPage() { if (String.IsNullOrEmpty(_controlToPage)) throw new Exception("Must set ControlToPage property"); return (GridView)Page.FindControl(_controlToPage); } public void RaisePostBackEvent(string eventArgument) { GridView grid = GetControlToPage(); grid.PageIndex = Int32.Parse(eventArgument); } }
} File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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 id="Head1" runat="server">
<title>Show CustomPager</title>
</head> <body>
<form id="form1" runat="server">
<asp:GridView id="GridView1" DataSourceID="srcProducts" AllowPaging="true" PageSize="3" PagerSettings-Visible="false" Runat="server" /> <custom:Pager id="Pager1" ControlToPage="GridView1" Runat="server" /> <asp:SqlDataSource id="srcProducts" ConnectionString="Data Source=.\SQLExpress;Integrated Security=True; AttachDbFileName=|DataDirectory|MyDatabase.mdf;User Instance=True" SelectCommand="SELECT Id,Title,Director FROM Products" Runat="server" />
</form>
</body> </html></source>
Creating a Container ControlDesigner
<source lang="csharp">
Add a reference to the System.Design.dll assembly to your application. using System; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.Design; using System.ruponentModel; using System.Drawing; namespace myControls {
[Designer(typeof(GradientPanelDesigner))] [ParseChildren(false)] public class GradientPanel : WebControl { private GradientDirection _direction = GradientDirection.Horizontal; private Color _startColor = Color.DarkBlue; private Color _endColor = Color.White; public GradientDirection Direction { get { return _direction; } set { _direction = value; } } public Color StartColor { get { return _startColor; } set { _startColor = value; } } public Color EndColor { get { return _endColor; } set { _endColor = value; } } protected override void AddAttributesToRender(HtmlTextWriter writer) { writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, this. GetFilterString()); base.AddAttributesToRender(writer); } public string GetFilterString() { return String.Format("progid:DXImageTransform.Microsoft.Gradient (gradientType={0},startColorStr={1},endColorStr={2})", _direction.ToString("d"), ColorTranslator.ToHtml(_startColor), ColorTranslator.ToHtml(_endColor)); } public GradientPanel() { this.Width = Unit.Parse("500px"); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } } } public enum GradientDirection { Vertical = 0, Horizontal = 1 } public class GradientPanelDesigner : ContainerControlDesigner { protected override void AddDesignTimeCssAttributes(System.Collections. IDictionary styleAttributes) { GradientPanel gPanel = (GradientPanel)this.ruponent; styleAttributes.Add("filter", gPanel.GetFilterString()); base.AddDesignTimeCssAttributes(styleAttributes); } }
}
Open the page in Design view in either Visual Web Developer or Visual Studio .NET.
File: ShowGradientPanel.aspx
<%@ Page Language="C#" %>
<%@ Register TagPrefix="custom" Namespace="myControls" %>
<!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 id="Head1" runat="server">
<title>Show GradientPanel</title>
</head> <body>
<form id="form1" runat="server">
<custom:GradientPanel id="GradientPanel1" Runat="server"> <asp:Calendar ID="Calendar1" runat="server" /> </custom:GradientPanel>
</form>
</body> </html></source>
Displaying a table of HTML colors.
<source lang="csharp">
using System; using System.Web.UI; using System.Web.UI.WebControls; using System.Drawing; namespace myControls {
public class ColorTable : WebControl { protected override void RenderContents(HtmlTextWriter writer) { KnownColor[] colors = (KnownColor[])Enum.GetValues(typeof(KnownColor)); writer.AddAttribute(HtmlTextWriterAttribute.Border, "1"); writer.RenderBeginTag(HtmlTextWriterTag.Table); foreach (KnownColor colorName in colors) { writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write(colorName); writer.RenderEndTag(); writer.AddAttribute(HtmlTextWriterAttribute.Width, "50px"); writer.AddAttribute(HtmlTextWriterAttribute.Bgcolor, colorName.ToString()); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write(" "); writer.RenderEndTag(); writer.RenderEndTag(); } writer.RenderEndTag(); } }
}</source>
File: DropShadow.cs
<source lang="csharp">
using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class DropShadow : WebControl { private string _Text; public string Text { get { return _Text; } set { _Text = value; } } protected override void RenderContents(HtmlTextWriter writer) { writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, "dropShadow(color=#AAAAAA,offX=3,offY=3);width:500px"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.Write(_Text); writer.RenderEndTag(); } }
}</source>
Handling Postback Events
<source lang="csharp">
File: CustomLinkButton.cs using System; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class CustomLinkButton : WebControl, IPostBackEventHandler { public event EventHandler Click; private string _Text; public string Text { get { return _Text; } set { _Text = value; } } protected override void AddAttributesToRender(HtmlTextWriter writer) { string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, String.Empty); writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef); base.AddAttributesToRender(writer); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.A; } } protected override void RenderContents(HtmlTextWriter writer) { writer.Write(_Text); }
public void RaisePostBackEvent(string eventArgument) { if (Click != null) Click(this, EventArgs.Empty); } }
}
File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
protected void CustomLinkButton1_Click(object sender, EventArgs e) { lblResults.Text = txtUserName.Text; }
</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">
<title>Show CustomLinkButton</title>
</head> <body>
<form id="form1" runat="server">
<asp:Label id="lblUserName" Text="User Name:" AssociatedControlID="txtUserName" Runat="server" /> <asp:TextBox id="txtUserName" Runat="server" />
<custom:CustomLinkButton id="CustomLinkButton1" Text="Submit" OnClick="CustomLinkButton1_Click" runat="server" />
<asp:Label id="lblResults" EnableViewState="false" Runat="server" />
</form>
</body> </html></source>
Processing Postback Data and Events
<source lang="csharp">
using System; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class CustomTextBox : WebControl, IPostBackDataHandler { public event EventHandler TextChanged; public string Text { get { if (ViewState["Text"] == null) return String.Empty; else return (string)ViewState["Text"]; } set { ViewState["Text"] = value; } } protected override void AddAttributesToRender(HtmlTextWriter writer) { writer.AddAttribute(HtmlTextWriterAttribute.Type, "text"); writer.AddAttribute(HtmlTextWriterAttribute.Value, Text); writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID); base.AddAttributesToRender(writer); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Input; } } public bool LoadPostData(string postDataKey, System.Collections. Specialized.NameValueCollection postCollection) { if (postCollection[postDataKey] != Text) { Text = postCollection[postDataKey]; return true; } return false; } public void RaisePostDataChangedEvent() { if (TextChanged != null) TextChanged(this, EventArgs.Empty); } }
} File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
protected void CustomTextBox1_TextChanged(object sender, EventArgs e) { lblResults.Text = CustomTextBox1.Text; }
</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">
<title>Show CustomTextBox</title>
</head> <body>
<form id="form1" runat="server">
<custom:CustomTextBox id="CustomTextBox1" OnTextChanged="CustomTextBox1_TextChanged" Runat="server" /> <asp:Button id="btnSubmit" Text="Submit" Runat="server" />
<asp:Label id="lblResults" Runat="server" />
</form>
</body> </html></source>
Specifying the Containing WebControl Tag
<source lang="csharp">
File: Glow.cs using System.Web.UI; using System.Web.UI.WebControls;namespace myControls {
public class Glow : WebControl { private string _Text; public string Text { get { return _Text; } set { _Text = value; } } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } } protected override void AddAttributesToRender(HtmlTextWriter writer) { writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, "glow(Color=#ffd700,Strength=10)"); base.AddAttributesToRender(writer); } protected override void RenderContents(HtmlTextWriter writer) { writer.Write(_Text); } public Glow() { this.Width = Unit.Parse("500px"); } }
}</source>
Supporting Control State
<source lang="csharp">
File: ControlStateControl.cs using System; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class ControlStateControl : WebControl { private string _controlStateText; public string ViewStateText { get { if (ViewState["ViewStateText"] == null) return String.Empty; else return (string)ViewState["ViewStateText"]; } set { ViewState["ViewStateText"] = value; } } public string ControlStateText { get { return _controlStateText; } set { _controlStateText = value; } } protected override void OnInit(EventArgs e) { Page.RegisterRequiresControlState(this); base.OnInit(e); } protected override object SaveControlState() { return _controlStateText; } protected override void LoadControlState(object savedState) { _controlStateText = (string)savedState; } protected override void RenderContents(HtmlTextWriter writer) { writer.Write("ViewStateText: " + ViewStateText); writer.WriteBreak(); writer.Write("ControlStateText: " + ControlStateText); writer.WriteBreak(); } }
}
File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
void Page_Load() { if (!Page.IsPostBack) { ControlStateControl1.ViewStateText = "Hello World!"; ControlStateControl1.ControlStateText = "Hello World!"; } }
</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">
<title>Show Control State</title>
</head> <body>
<form id="form1" runat="server">
<custom:ControlStateControl id="ControlStateControl1" EnableViewState="false" Runat="server" /> <asp:Button id="btnSubmit" Text="Submit" Runat="server" />
</form>
</body> </html></source>
Using a ControlBuilder
<source lang="csharp">
File: ServerTabs.cs using System; using System.Collections; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
[ControlBuilder(typeof(ServerTabsBuilder))] [ParseChildren(false)] public class ServerTabs : WebControl, IPostBackEventHandler { public int SelectedTabIndex { get { if (ViewState["SelectedTabIndex"] == null) return 0; else return (int)ViewState["SelectedTabIndex"]; } set { ViewState["SelectedTabIndex"] = value; } } protected override void RenderContents(HtmlTextWriter writer) { for (int i = 0; i < this.Controls.Count; i++) { ServerTab tab = (ServerTab)this.Controls[i]; string eRef = Page.ClientScript.GetPostBackClientHyperlink(this, i.ToString()); if (SelectedTabIndex == i) writer.AddAttribute(HtmlTextWriterAttribute.Class, "tab selectedTab"); else writer.AddAttribute(HtmlTextWriterAttribute.Class, "tab"); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.AddAttribute(HtmlTextWriterAttribute.Href, eRef); writer.RenderBeginTag(HtmlTextWriterTag.A); writer.Write(tab.Text); writer.RenderEndTag(); writer.RenderEndTag(); } writer.Write("
"); writer.AddAttribute(HtmlTextWriterAttribute.Class, "tabContents"); writer.RenderBeginTag(HtmlTextWriterTag.Div); this.Controls[SelectedTabIndex].RenderControl(writer); writer.RenderEndTag(); } protected override void AddParsedSubObject(object obj) { if (obj is ServerTab) base.AddParsedSubObject(obj); } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Div; } } public void RaisePostBackEvent(string eventArgument) { SelectedTabIndex = Int32.Parse(eventArgument); } } public class ServerTabsBuilder : ControlBuilder { public override Type GetChildControlType(string tagName, IDictionary attribs) { if (String.rupare(tagName, "tab", true) == 0) return typeof(ServerTab); else return null; } } public class ServerTab : Control { private string _Text; public string Text { get { return _Text; } set { _Text = value; } } }
}
File: ShowServerTabs.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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 id="Head1" runat="server">
<style type="text/css"> .tab { float:left; position:relative; top:1px; background-color:#eeeeee; border:solid 1px black; padding:0px 15px; margin-left:5px; } .tab a { text-decoration:none; } .selectedTab { background-color:white; border-bottom:solid 1px white; } .tabContents { border:solid 1px black; background-color:white; padding:10px; height:200px; } </style> <title>Show ServerTabs</title>
</head> <body>
<form id="form1" runat="server">
<custom:ServerTabs ID="ServerTabs1" Runat="Server"> <tab Text="First Tab"> Contents of the first tab </tab> <tab Text="Second Tab"> Contents of the second tab </tab> <tab Text="Third Tab"> Contents of the third tab </tab> </custom:ServerTabs>
</form>
</body> </html></source>
Using Postback Options
<source lang="csharp">
File: AdvancedCheckBox.cs using System; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class AdvancedCheckBox : WebControl { private string _Text; private string _PostBackUrl; public string Text { get { return _Text; } set { _Text = value; } } public string PostBackUrl { get { return _PostBackUrl; } set { _PostBackUrl = value; } } protected override void AddAttributesToRender(HtmlTextWriter writer) { PostBackOptions options = new PostBackOptions(this); options.ActionUrl = _PostBackUrl; string eRef = Page.ClientScript.GetPostBackEventReference(options); writer.AddAttribute(HtmlTextWriterAttribute.Onclick, eRef); writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID); writer.AddAttribute(HtmlTextWriterAttribute.Type, "checkbox");
base.AddAttributesToRender(writer); } protected override void RenderContents(HtmlTextWriter writer) { if (!String.IsNullOrEmpty(_Text)) { writer.AddAttribute(HtmlTextWriterAttribute.For, this.ClientID); writer.RenderBeginTag(HtmlTextWriterTag.Label); writer.Write(_Text); writer.RenderEndTag(); } } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Input; } } }
} File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
public string ProductName { get { return txtProductName.Text; } }
</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">
<title>Show AdvancedCheckBox</title>
</head> <body>
<form id="form1" runat="server">
<asp:Label id="lblProductName" Text="Product Name:" AssociatedControlID="txtProductName" Runat="server" /> <asp:TextBox id="txtProductName" Runat="server" />
<custom:AdvancedCheckBox id="AdvancedCheckBox1" Text="Advanced Options" PostBackUrl="AdvancedOptions.aspx" Runat="server" />
</form>
</body> </html></source>
View State and Control State
<source lang="csharp">
using System; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class ViewStateControl : WebControl { private string _text; public string Text { get { return _text; } set { _text = value; } } public string ViewStateText { get { if (ViewState["ViewStateText"] == null) return String.Empty; else return (string)ViewState["ViewStateText"]; } set { ViewState["ViewStateText"] = value; } } protected override void RenderContents(HtmlTextWriter writer) { writer.Write("Text: " + Text); writer.WriteBreak(); writer.Write("ViewStateText: " + ViewStateText); writer.WriteBreak(); } }
}
File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
void Page_Load() { if (!Page.IsPostBack) { ViewStateControl1.Text = "Hello World!"; ViewStateControl1.ViewStateText = "Hello World!"; } }
</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">
<title>Show View State</title>
</head> <body>
<form id="form1" runat="server">
<custom:ViewStateControl id="ViewStateControl1" Runat="server" /> <asp:Button id="btnSubmit" Text="Submit" Runat="server" />
</form>
</body> </html></source>
Working with Control Property Collections
<source lang="csharp">
File: ContentRotator.cs using System; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
[ParseChildren(false)] public class ContentRotator : WebControl { protected override void AddParsedSubObject(object obj) { if (obj is Content) base.AddParsedSubObject(obj); } protected override void RenderContents(HtmlTextWriter writer) { Random rnd = new Random(); int index = rnd.Next(this.Controls.Count); this.Controls[index].RenderControl(writer); } } public class Content : Control { }
}
File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!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 id="Head1" runat="server">
<title>Show ContentRotator</title>
</head> <body>
<form id="form1" runat="server">
<custom:ContentRotator id="ContentRotator1" Runat="server"> <custom:Content id="Content1" Runat="server"> First Content Item </custom:Content> <custom:Content id="Content2" Runat="server"> Second Content Item <asp:Calendar id="Calendar1" Runat="server" /> </custom:Content> <custom:Content id="Content3" Runat="server"> Third Content Item </custom:Content> </custom:ContentRotator>
</form>
</body> </html></source>
You can add your own Smart Tasks to a custom control by inheriting a new class from the base DesignerActionList class.
<source lang="csharp">
using System; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.Design;using System.ruponentModel; using System.ruponentModel.Design; namespace myControls {
[Designer(typeof(SmartImageDesigner))] public class SmartImage : WebControl { string _imageUrl; string _alternateText; int _rotation = 0; bool _mirror = false; public string ImageUrl { get { return _imageUrl; } set { _imageUrl = value; } } public string AlternateText { get { return _alternateText; } set { _alternateText = value; } } public int Rotation { get { return _rotation; } set { _rotation = value; } } public bool Mirror { get { return _mirror; } set { _mirror = value; } } protected override HtmlTextWriterTag TagKey { get { return HtmlTextWriterTag.Img; } } private string GetFilterString() { string _mirrorValue = "0"; if (_mirror) _mirrorValue = "1"; return String.Format("progid:DXImageTransform.Microsoft. BasicImage(Rotation={0},Mirror={1})", _rotation, _mirrorValue); } protected override void AddAttributesToRender(HtmlTextWriter writer) { writer.AddStyleAttribute(HtmlTextWriterStyle.Filter, this. GetFilterString()); writer.AddAttribute(HtmlTextWriterAttribute.Src, _imageUrl); writer.AddAttribute(HtmlTextWriterAttribute.Alt, _alternateText);
base.AddAttributesToRender(writer); } } public class SmartImageDesigner : ControlDesigner { public override DesignerActionListCollection ActionLists { get { DesignerActionListCollection actionLists = new DesignerActionListCollection(); actionLists.AddRange(base.ActionLists); actionLists.Add(new SmartImageActionList(this)); return actionLists; } } } public class SmartImageActionList : DesignerActionList { private DesignerActionItemCollection items; private SmartImageDesigner _parent; public SmartImageActionList(SmartImageDesigner parent) : base(parent.ruponent) { _parent = parent; } public void Rotate() { TransactedChangeCallback toCall = new TransactedChangeCallback(DoRotate); ControlDesigner.InvokeTransactedChange(this.ruponent, toCall, "Rotate", "Rotate image 90 degrees"); } public void Mirror() { TransactedChangeCallback toCall = new TransactedChangeCallback(DoMirror); ControlDesigner.InvokeTransactedChange(this.ruponent, toCall, "Mirror", "Mirror Image"); } public override DesignerActionItemCollection GetSortedActionItems() { if (items == null) { items = new DesignerActionItemCollection(); items.Add(new DesignerActionMethodItem(this, "Rotate", "Rotate Image", true)); items.Add(new DesignerActionMethodItem(this, "Mirror", "Mirror Image", true)); } return items; } public bool DoRotate(object arg) { SmartImage img = (SmartImage)this.ruponent; img.Rotation += 1; if (img.Rotation > 3) img.Rotation = 0; _parent.UpdateDesignTimeHtml(); return true; } public bool DoMirror(object arg) { SmartImage img = (SmartImage)this.ruponent; img.Mirror = !img.Mirror; _parent.UpdateDesignTimeHtml(); return true; } }
}</source>
Your own data binding control
<source lang="csharp">
File: Article.cs using System; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace myControls {
public class Article : CompositeControl { private string _title; private string _author; private string _contents; private ITemplate _itemTemplate; public string Title { get { return _title; } set { _title = value; } } public string Author { get { return _author; } set { _author = value; } } public string Contents { get { return _contents; } set { _contents = value; } } [TemplateContainer(typeof(Article))] [PersistenceMode(PersistenceMode.InnerProperty)] public ITemplate ItemTemplate { get { return _itemTemplate; } set { _itemTemplate = value; } } protected override void CreateChildControls() { _itemTemplate.InstantiateIn(this); } }
}
File: Default.aspx <%@ Page Language="C#" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server">
void Page_Load() { Article1.Title = "your title"; Article1.Author = "your name"; Article1.Contents = "Blah, blah, blah, blah..."; Article1.DataBind(); }
</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">
<title>Show Article</title>
</head> <body>
<form id="form1" runat="server">
<custom:Article id="Article1" Runat="server"> <ItemTemplate>
<%# Container.Title %>
By <%# Container.Author %>
<%# Container.Contents %> </ItemTemplate> </custom:Article>
</form>
</body> </html></source>