I got a report from a user today that one of my controls isn’t working correctly when using absolute positioning in the ASP.NET designer. I never use absolute positioning and so I never actually noticed this before <blush>… The control renders fine and in the designer, but the control wasn’t movable in the designer when absolute positioning was set on the control. The Visual Studio designer lets you drag controls around when absolute positioning is on.
Well, it turns out that the control indeed didn’t work properly in the designer and it took some time to figure out what the problem was. The control is an error display control which basically renders an HTML Table into the page.
The problem is that if control rendering for design-time has any prefix or postfix tags around the ‘main’ control that hosts the positional styles, the control won’t be draggable in the designer.
In this case of the control I was working on I actually have a a <div> wrapper I often place around block controls so they render properly in the designer. The control also had a trailing <br /> to add some extra white space (better served by padding in retrospect <s>). In both cases the main control is not the outer tag that the designer sees and hence it fails dragging controls around. Note it still renders correctly if you manually change the positional elements – it’s just the dragging that doesn’t work.
So if building a composite control that has potential outer wrappers at design time might require checking for the absolute positioning in the Render() or ControlDesigner code.
Something like this:
protected override void Render(HtmlTextWriter writer)
{
if (Text == "" && !this.DesignMode)
{
base.Render(writer);
return;
}
if (RenderMode == RenderModes.Text)
Text = wwUtils.DisplayMemo(this.Text);
string TStyle = this.Style["position"];
bool IsAbsolute = false;
if (TStyle != null && TStyle.Trim() == "absolute")
IsAbsolute = true;
// *** <Center> is still the only reliable way to get block structures centered
if (!IsAbsolute && this.Center)
writer.RenderBeginTag(HtmlTextWriterTag.Center);
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, this.CellPadding);
writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "30px");
writer.AddStyleAttribute(HtmlTextWriterStyle.Width, this.Width.ToString());
writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "left");
foreach(string Key in this.Style.Keys)
{
writer.AddStyleAttribute(Key, this.Style[Key]);
}
writer.RenderBeginTag(HtmlTextWriterTag.Table);
…
writer.RenderEndTag(); // <table>
if (!IsAbsolute)
{
if (this.Center)
writer.RenderEndTag(); // </center>
writer.WriteBreak();
}
}
The same would apply with a ControlDesigner...
Incidentally I had no luck with:
this.Style[HtmlTextWriterStyle.Position]
which didn’t properly return the “absolute” value for some reason, while:
string TStyle = this.Style["position"];
worked properly.
Other Posts you might also like