I've got the the following custom RadioButtonList control and ControlDesigner, but when I go to view the control in the Visual Studio designer (when mounted on a page), the control isn't showing the list items if I set any of the list related properties
(such as AutoPostback) in the declarative code of the page that uses the control.
I have to say, I'm new to designing Server Controls and may have totally got the wrong end of the stick with this. Ideally, I would have just inherited from RadioButtonList I think, but I need my controls to share some common functionality with other controls
I have (of a different base type) and can't see any other way of doint it.
Can anyone help please?
Control
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Permissions;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
using System.Web.UI.Design.WebControls;
// The following properties are delegated to
// child controls.
[
Bindable(true),
Category("Indigo"),
DefaultValue(""),
Description("Items contained within the Radio Button List."),
PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public RadioButtonListItems Items { get; private set; }
//[
//Bindable(true),
//Category("Indigo"),
//DefaultValue(""),
//Description("Determines whether items that are added during databinding should be appended or the list should be cleared first.")
//]
//public bool AppendDataBoundItems
//{
// get
// {
// EnsureChildControls();
// return _radioButtonList.AppendDataBoundItems;
// }
// set
// {
// EnsureChildControls();
// _radioButtonList.AppendDataBoundItems = value;
// }
//}
//[
//Bindable(true),
//Category("Indigo"),
//DefaultValue(""),
//Description("Number of columns to repeat in the given direction.")
//]
//public int RepeatColumns
//{
// get
// {
// EnsureChildControls();
// return _radioButtonList.RepeatColumns;
// }
// set
// {
// EnsureChildControls();
// _radioButtonList.RepeatColumns = value;
// }
//}
[
Browsable(false),
Bindable(true),
Category("Indigo"),
DefaultValue(""),
Description("Selected index.")
]
public int SelectedIndex
{
get
{
EnsureChildControls();
return _radioButtonList.SelectedIndex;
}
// set
// {
// EnsureChildControls();
// _radioButtonList.SelectedIndex = value;
// }
}
[
Bindable(true),
Category("Indigo"),
DefaultValue(""),
Description("Determines whether a postback should be raised when an item is selected.")
]
public bool AutoPostBack
{
get
{
EnsureChildControls();
return _radioButtonList.AutoPostBack;
}
set
{
EnsureChildControls();
_radioButtonList.AutoPostBack = value;
}
}
public override bool IsValid
{
get
{ return base.IsValid; }
set
{
if (value == true)
_radioButtonList.BorderColor = System.Drawing.ColorTranslator.FromHtml("#aec2ab");
else
_radioButtonList.BorderColor = System.Drawing.Color.Red;
base.IsValid = value;
}
}
public object GetControlData()
{
var controlData = new IndigoListItem(_radioButtonList.SelectedItem.Value, _radioButtonList.SelectedItem.Text);
return (controlData);
}
public void SetControlData(object controlData)
{
_radioButtonList.SelectedValue = ((IndigoListItem)controlData).Value;
}
#endregion
}
public class RadioButtonListItems : List<ListItem>
{
}
}
Control Designer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.Design.WebControls;
using System.Web.UI.Design;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
namespace SouthSomerset.UmbracoIndigo.Controls
{
class IndigoDataControlDesigner : CompositeControlDesigner
{
IndigoDataControl dataControl;
As far as I know, the method "CreateChildControls" won't be executed automatically until you use EnableChildControls. And then it will check ChildControlsCreated=true or false, if true, the codes will be ignored and false the codes will be executed.
But your problem is that you've used the constructor, this will be executed everytime so your items are always empty.
My solution:
1) Delete the constructor first.
2) Initialize it in the CreateChildControls method, and set ChildControlsCreated=false.
protected override void CreateChildControls()
{
Controls.Clear();
_radioButtonList = new RadioButtonList();
_radioButtonList.AutoPostBack = true;
this.Items = new RadioButtonListItems();
foreach (var item in Items)
{
_radioButtonList.Items.Add(item);
}
this.Controls.Add(_radioButtonList);
mbettesworth
Member
6 Points
10 Posts
ControlDesigner and RadioButtonList
Oct 29, 2011 02:11 AM|LINK
Hi,
I've got the the following custom RadioButtonList control and ControlDesigner, but when I go to view the control in the Visual Studio designer (when mounted on a page), the control isn't showing the list items if I set any of the list related properties (such as AutoPostback) in the declarative code of the page that uses the control.
I have to say, I'm new to designing Server Controls and may have totally got the wrong end of the stick with this. Ideally, I would have just inherited from RadioButtonList I think, but I need my controls to share some common functionality with other controls I have (of a different base type) and can't see any other way of doint it.
Can anyone help please?
Control
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Permissions;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
using System.Web.UI.Design.WebControls;
namespace SouthSomerset.UmbracoIndigo.Controls
{
[
AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal),
//DefaultEvent("Submit"),
DefaultProperty("ID"),
//PersistChildren(true),
ParseChildren(ChildrenAsProperties = true),
Designer(typeof(IndigoDataControlDesigner)),
ToolboxData("<{0}:IndigoRadioButtonList runat=\"server\"> </{0}:IndigoRadioButtonList>"),
]
public class IndigoRadioButtonList : IndigoDataControl, INamingContainer, IIndigoDataControl
{
#region Members
private RadioButtonList _radioButtonList;
#endregion
#region Constructor(s) / Destructor(s)
public IndigoRadioButtonList()
{
this.Items = new RadioButtonListItems();
}
#endregion
#region Properties
// The following properties are delegated to
// child controls.
[
Bindable(true),
Category("Indigo"),
DefaultValue(""),
Description("Items contained within the Radio Button List."),
PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public RadioButtonListItems Items { get; private set; }
//[
//Bindable(true),
//Category("Indigo"),
//DefaultValue(""),
//Description("Determines whether items that are added during databinding should be appended or the list should be cleared first.")
//]
//public bool AppendDataBoundItems
//{
// get
// {
// EnsureChildControls();
// return _radioButtonList.AppendDataBoundItems;
// }
// set
// {
// EnsureChildControls();
// _radioButtonList.AppendDataBoundItems = value;
// }
//}
//[
//Bindable(true),
//Category("Indigo"),
//DefaultValue(""),
//Description("Number of columns to repeat in the given direction.")
//]
//public int RepeatColumns
//{
// get
// {
// EnsureChildControls();
// return _radioButtonList.RepeatColumns;
// }
// set
// {
// EnsureChildControls();
// _radioButtonList.RepeatColumns = value;
// }
//}
//[
//Bindable(true),
//Category("Indigo"),
//DefaultValue(""),
//Description("Direction to repeat items.")
//]
//public RepeatDirection RepeatDirection
//{
// get
// {
// //EnsureChildControls();
// return _radioButtonList.RepeatDirection;
// }
// set
// {
// EnsureChildControls();
// _radioButtonList.RepeatDirection = value;
// }
//}
[
Browsable(false),
Bindable(true),
Category("Indigo"),
DefaultValue(""),
Description("Selected index.")
]
public int SelectedIndex
{
get
{
EnsureChildControls();
return _radioButtonList.SelectedIndex;
}
// set
// {
// EnsureChildControls();
// _radioButtonList.SelectedIndex = value;
// }
}
[
Bindable(true),
Category("Indigo"),
DefaultValue(""),
Description("Determines whether a postback should be raised when an item is selected.")
]
public bool AutoPostBack
{
get
{
EnsureChildControls();
return _radioButtonList.AutoPostBack;
}
set
{
EnsureChildControls();
_radioButtonList.AutoPostBack = value;
}
}
#endregion
#region Methods
protected override void CreateChildControls()
{
Controls.Clear();
_radioButtonList = new RadioButtonList();
_radioButtonList.AutoPostBack = true;
//_textBox.ID = "textBox" + ID;
//_textBox.EnableEmbeddedSkins = false;
foreach (var item in Items)
{
_radioButtonList.Items.Add(item);
}
this.Controls.Add(_radioButtonList);
//base.CreateChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
RenderBeginTag(writer);
RenderDataControlBeginLine(writer);
//base.RenderContents(writer);
RenderChildren(writer);
RenderDataControlEndLine(writer);
RenderEndTag(writer);
}
public virtual bool CheckValidity()
{
EnsureChildControls();
if ((_radioButtonList.SelectedIndex < 0 && Required == true))
IsValid = false;
else
IsValid = true;
return IsValid;
}
public override bool IsValid
{
get
{ return base.IsValid; }
set
{
if (value == true)
_radioButtonList.BorderColor = System.Drawing.ColorTranslator.FromHtml("#aec2ab");
else
_radioButtonList.BorderColor = System.Drawing.Color.Red;
base.IsValid = value;
}
}
public object GetControlData()
{
var controlData = new IndigoListItem(_radioButtonList.SelectedItem.Value, _radioButtonList.SelectedItem.Text);
return (controlData);
}
public void SetControlData(object controlData)
{
_radioButtonList.SelectedValue = ((IndigoListItem)controlData).Value;
}
#endregion
}
public class RadioButtonListItems : List<ListItem>
{
}
}
Control Designer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.Design.WebControls;
using System.Web.UI.Design;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
namespace SouthSomerset.UmbracoIndigo.Controls
{
class IndigoDataControlDesigner : CompositeControlDesigner
{
IndigoDataControl dataControl;
//public override void Initialize(System.ComponentModel.IComponent component)
//{
//IndigoDataControl dataControl = (IndigoDataControl)component;
//base.Initialize(component);
//}
protected override bool UsePreviewControl
{
get
{
return true;
}
}
public override bool AllowResize
{
get
{
return false;
}
}
public override string GetDesignTimeHtml(System.Web.UI.Design.DesignerRegionCollection regions)
{
StringWriter sw = new StringWriter();
HtmlTextWriter tw = new HtmlTextWriter(sw);
((IndigoDataControl)base.Component).Controls[0].RenderControl(tw);
//<div class=\"{1}\" style=\"{2}\">\r\n<div class=\"{3}\" {0}=0></div>\r\n</div>{4}"
//return base.GetDesignTimeHtml(regions);
return string.Format(CultureInfo.InvariantCulture, "<div class=\"{0}\" style=\"{1}\">\r\n<table >\r\n<tr style=\"vertical-align:top;\">\r\n<td style=\"width:{2};\">{3}{6}{7}</td>\r\n<td>{5}</td>\r\n</tr>\r\n</table>\r\n</div>{4}",
((IndigoDataControl)base.Component).CSS,
((IndigoDataControl)base.Component).Style,
((IndigoDataControl)base.Component).LabelWidth.ToString(),
String.IsNullOrEmpty(((IndigoDataControl)base.Component).LabelText) == true ? "[" + ((IndigoDataControl)base.Component).ID + "]" : ((IndigoDataControl)base.Component).LabelText,
((IndigoDataControl)base.Component).ClearRequired ? "<div class=\"clear\"></div>" : String.Empty,
sw.ToString(),
((IndigoDataControl)base.Component).Required ? "<span class=\"required\"> *</span>" : String.Empty,
(String.IsNullOrEmpty(((IndigoDataControl)base.Component).ToolTip) == false) ? "<span class=\"required\"> *</span>" : String.Empty);
}
}
}
Thanks,
Matt
Decker Dong ...
All-Star
118619 Points
18779 Posts
Re: ControlDesigner and RadioButtonList
Oct 31, 2011 01:48 AM|LINK
Hello:)
As far as I know, the method "CreateChildControls" won't be executed automatically until you use EnableChildControls. And then it will check ChildControlsCreated=true or false, if true, the codes will be ignored and false the codes will be executed.
But your problem is that you've used the constructor, this will be executed everytime so your items are always empty.
My solution:
1) Delete the constructor first.
2) Initialize it in the CreateChildControls method, and set ChildControlsCreated=false.
protected override void CreateChildControls()
{
Controls.Clear();
_radioButtonList = new RadioButtonList();
_radioButtonList.AutoPostBack = true;
this.Items = new RadioButtonListItems();
foreach (var item in Items)
{
_radioButtonList.Items.Add(item);
}
this.Controls.Add(_radioButtonList);
ChildControlsCreated=true;
}