I need a Server Control (named FormLayout
here) that renders child controls based on their attribute.
The goal is to be able to write something like the following:
<custom:FormLayout runat="server" ID="myForm">
<custom:MyDropDownList runat="server" ID="field1" ColumnSpan="12"></custom:MyDropDownList>
<custom:MyTextBox runat="server" ID="field2"></custom:MyTextBox>
</custom:FormLayout>
This is the current implementation for these server controls: (In reality there will be more types of child server control, not only these two.)
public interface ICommonFieldProperties{
public int ColumnSpan {get;set;}
}
public class MyDropDownList:System.Web.UI.WebControls.DropDownList,
ICommonFieldProperties {
public int ColumnSpan {get;set;}
}
public class MyTextBox:System.Web.UI.WebControls.TextBox,
ICommonFieldProperties {
public int ColumnSpan {get;set;}
}
public class FormLayout:Panel{
protected override void RenderContents(HtmlTextWriter writer){
foreach (Control i in Controls)
// can't access the newly added common properties such as "ColumnSpan"
i.RenderControl(writer);
}
I tried to add the common properties by inheriting a common interface, but then I need to cast these child controls to ICommonFieldProperties
whenever I want to access properties defined in it and cast them back to Control
whenever I want to use the methods inherited from Control
. For exmaple:
protected override void RenderContents(HtmlTextWriter writer) {
var orderedControls = Controls
.OfType<ICommonFieldProperties>()
.Where(c => c.ColumnSpan == 0);
foreach (var field in orderedControls){
// Group them into different wrappers based on some other common properties in ICommon Field
// ...
// render
((Control)field).RenderControl(writer);
}
}
Another big problem is that since this is on .Net 4.8, interfaces don’t support default methods so I will need to duplicate every implementation for methods/auto properties in ICommonFieldProperties
in each child server control even if they are all the same. Is there an easier way to do this?
2
Answers
Separate
FormSlot
elements fromControl
elements.Since the
common properties
you mentioned seem to be all layout-related.If so, it’s better to abstract the
FormSlot
fromControl
itself, which acts more like acontainer
for setting arranging properties such as theColumnSpan
you mentioned above.