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
A control that inherits from the WebControl class.
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">
<div>
<custom:FullyRenderedWebControl
ID="FullyrenderedWebControl1"
Text="Hello World"
BackColor="Yellow"
BorderStyle="Dashed"
Font-Size="32px"
Runat="Server" />
</div>
</form>
</body>
</html>
Applying Design-Time Attributes to a Control
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">
<div>
<custom:ProductView
id="ProductView1"
Runat="server" />
</div>
</form>
</body>
</html>
contains the custom pager control.
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">
<div>
<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" />
</div>
</form>
</body>
</html>
Creating a Container ControlDesigner
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">
<div>
<custom:GradientPanel
id="GradientPanel1"
Runat="server">
<asp:Calendar
ID="Calendar1"
runat="server" />
</custom:GradientPanel>
</div>
</form>
</body>
</html>
Displaying a table of HTML colors.
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();
}
}
}
File: DropShadow.cs
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();
}
}
}
Handling Postback Events
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">
<div>
<asp:Label
id="lblUserName"
Text="User Name:"
AssociatedControlID="txtUserName"
Runat="server" />
<asp:TextBox
id="txtUserName"
Runat="server" />
<br /><br />
<custom:CustomLinkButton
id="CustomLinkButton1"
Text="Submit"
OnClick="CustomLinkButton1_Click"
runat="server" />
<hr />
<asp:Label
id="lblResults"
EnableViewState="false"
Runat="server" />
</div>
</form>
</body>
</html>
Processing Postback Data and Events
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">
<div>
<custom:CustomTextBox
id="CustomTextBox1"
OnTextChanged="CustomTextBox1_TextChanged"
Runat="server" />
<asp:Button id="btnSubmit"
Text="Submit"
Runat="server" />
<hr />
<asp:Label
id="lblResults"
Runat="server" />
</div>
</form>
</body>
</html>
Specifying the Containing WebControl Tag
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");
}
}
}
Supporting Control State
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">
<div>
<custom:ControlStateControl
id="ControlStateControl1"
EnableViewState="false"
Runat="server" />
<asp:Button
id="btnSubmit"
Text="Submit"
Runat="server" />
</div>
</form>
</body>
</html>
Using a ControlBuilder
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("<br style="clear:both" />");
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">
<div>
<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>
</div>
</form>
</body>
</html>
Using Postback Options
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">
<div>
<asp:Label
id="lblProductName"
Text="Product Name:"
AssociatedControlID="txtProductName"
Runat="server" />
<asp:TextBox
id="txtProductName"
Runat="server" />
<br /><br />
<custom:AdvancedCheckBox
id="AdvancedCheckBox1"
Text="Advanced Options"
PostBackUrl="AdvancedOptions.aspx"
Runat="server" />
</div>
</form>
</body>
</html>
View State and Control State
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">
<div>
<custom:ViewStateControl
id="ViewStateControl1"
Runat="server" />
<asp:Button
id="btnSubmit"
Text="Submit"
Runat="server" />
</div>
</form>
</body>
</html>
Working with Control Property Collections
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">
<div>
<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>
</div>
</form>
</body>
</html>
You can add your own Smart Tasks to a custom control by inheriting a new class from the base DesignerActionList class.
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;
}
}
}
Your own data binding control
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">
<div>
<custom:Article
id="Article1"
Runat="server">
<ItemTemplate>
<h1><%# Container.Title %></h1>
<em>By <%# Container.Author %></em>
<br /><br />
<%# Container.Contents %>
</ItemTemplate>
</custom:Article>
</div>
</form>
</body>
</html>