Introduction
Developing websites with dynamic content can lead to the following requirements:
- Enable or disable controls dependent on the state of another control
- Hide or show controls dependent on the visibility of another control
- Invert state/visibility dependent on the state/visibility of another control
The
AdapterControl
supports these kinds of operations, without the need to change the code behind.
Background
AdapterControl
represents a simple control without a visual representation. The activity area is restricted to the child controls of his parent:
public class AdapterControl : Control
{
public enum AdaptMode
{
None,
Unvaried,
Inverted,
}
[Themeable( false )]
public string SourceControl { get; set; }
[Themeable( false )]
public string TargetControl { get; set; }
[Themeable( false )]
public AdaptMode EnabledMode { get; set; }
[Themeable( false )]
public AdaptMode VisibleMode { get; set; }
protected override void OnPreRender( EventArgs e )
{
base.OnPreRender( e );
if ( string.IsNullOrEmpty( SourceControl ) )
{
Trace.WriteLine( "AdapterControl: missing source control" );
return;
}
Control source = Parent.FindControl( SourceControl );
if ( source == null )
{
Trace.WriteLine( "AdapterControl: source control '" + SourceControl + "' not found" );
return;
}
if ( string.IsNullOrEmpty( TargetControl ) )
{
Trace.WriteLine( "AdapterControl: missing target control" );
return;
}
Control target = Parent.FindControl( TargetControl );
if ( target == null )
{
Trace.WriteLine( "AdapterControl: target control '" + TargetControl + "' not found" );
return;
}
switch ( VisibleMode )
{
case AdaptMode.Unvaried:
target.Visible = source.Visible;
break;
case AdaptMode.Inverted:
target.Visible = !source.Visible;
break;
}
if ( target.Visible && EnabledMode != AdaptMode.None )
{
WebControl sourceWebControl = source as WebControl;
WebControl targetWebControl = target as WebControl;
if ( sourceWebControl != null && targetWebControl != null )
{
switch ( EnabledMode )
{
case AdaptMode.Unvaried:
targetWebControl.Enabled = sourceWebControl.Enabled;
break;
case AdaptMode.Inverted:
targetWebControl.Enabled = !sourceWebControl.Enabled;
break;
}
}
}
}
}
Using the code
As a prerequisite you have to specify the source and target control using the properties SourceControl
and TargetControl
:
<Controls:AdapterControl runat="server" SourceControl="SourceID" TargetControl="TargetID" />
The AdapterControl
allows you to adapt the enabling state through the property EnabledMode
. The visibility can be adapted using the property VisibleMode
.
The adaption will be regulated by the enumeration AdaptMode
:
None
: do not adapt the value (default) Unvaried
: adapt the value from the source control one-to-one to the target control Inverted
: adapt the inverted value from the source control to the target control
The following example allows you to switch between two login variations. It demonstrates the EnabledMode
controlled by the buttons Enable and Disable and the VisibleMode
by the buttons Default Login and Alternate Login:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="Controls" Namespace="Itenso.Community.AdapterControl.Controls" Assembly="Itenso.Community.AdapterControl.Controls" %>
<!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>Demo AdapterControl</title>
</head>
<body>
<form id="form1" runat="server">
<h1>
Demo AdapterControl</h1>
<Controls:AdapterControl runat="server" SourceControl="DefaultLoginSettings" TargetControl="AlternateLoginSettings" VisibleMode="Inverted" />
<Controls:AdapterControl runat="server" SourceControl="DefaultLoginSettings" TargetControl="NameButton" VisibleMode="Inverted" />
<asp:Button runat="server" ID="NameButton" OnClick="NameMode" Text="Default Login" />
<Controls:AdapterControl runat="server" SourceControl="DefaultLoginSettings" TargetControl="AlternateLoginButton" VisibleMode="Unvaried" />
<asp:Button runat="server" ID="AlternateLoginButton" OnClick="AlternateLoginMode" Text="Alternate Login" />
<Controls:AdapterControl runat="server" SourceControl="DefaultLoginSettings" TargetControl="DefaultLoginInfoLabel" VisibleMode="Unvaried" />
<asp:Label runat="server" ID="DefaultLoginInfoLabel" Text="Current Mode: Default Login" />
<Controls:AdapterControl runat="server" SourceControl="AlternateLoginSettings" TargetControl="AlternateLoginInfoLabel" VisibleMode="Unvaried" />
<asp:Label runat="server" ID="AlternateLoginInfoLabel" Text="Current Mode: Alternate Login" />
<br />
<br />
<asp:Panel runat="server" GroupingText="Login">
<asp:Table runat="server">
<asp:TableRow runat="server" ID="DefaultLoginSettings">
<asp:TableCell>
<asp:Label runat="server" Text="Name:" />
</asp:TableCell>
<asp:TableCell>
<asp:TextBox runat="server" />
<asp:CheckBox runat="server" Text="Make public" />
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell />
<asp:TableCell>
<Controls:AdapterControl runat="server" SourceControl="DefaultLoginSettings" TargetControl="EnableNameOption" VisibleMode="Unvaried" EnabledMode="Inverted" />
<asp:Button runat="server" ID="EnableNameOption" OnClick="EnableLogin" Text="Enable" />
<Controls:AdapterControl runat="server" SourceControl="DefaultLoginSettings" TargetControl="DisableNameOption" VisibleMode="Unvaried" EnabledMode="Unvaried" />
<asp:Button runat="server" ID="DisableNameOption" OnClick="DisableLogin" Text="Disable" />
</asp:TableCell>
</asp:TableRow>
<asp:TableRow runat="server" ID="AlternateLoginSettings">
<asp:TableCell>
<asp:Label runat="server" Text="Name:" />
</asp:TableCell>
<asp:TableCell>
<asp:TextBox runat="server" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:Panel>
</form>
</body>
</html>
Points of Interest
- source and target have to be a child control of the
AdapterControl
's parent control - in case of control dependencies, you have to regard the declaration order
- the enabling will not be adapted, in case the target control is hidden
History
29th March 2012: Initial version