views:

1399

answers:

3

Greetings!

I've created a custom button class to render the following:

<span class="btnOrange">
    <input type="submit" id="ctl00_MainContent_m_GoBack" value="Back" name="ctl00$MainContent$m_GoBack"/>
</span>

However, it renders like this instead (note the extraneous "class" attribute in the INPUT tag):

<span class="btnOrange">
    <input type="submit" class="btnOrange" id="ctl00_MainContent_m_GoBack" value="Back" name="ctl00$MainContent$m_GoBack"/>
</span>

My custom button class looks like this:

[ToolboxData(@"<{0}:MyButton runat=server></{0}:MyButton>")]
public class MyButton : Button
{
    public override void RenderBeginTag(HtmlTextWriter writer)
    {
       writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);   
       writer.RenderBeginTag("span");
       base.RenderBeginTag(writer);
    }

    public override void RenderEndTag(HtmlTextWriter writer)
    {
       writer.RenderEndTag();
       base.RenderEndTag(writer);
    }
}

Since I only need to set the class attribute for the SPAN tag, is it possible to not include or "blank out" the class attribute for the INPUT tag?

A: 

How about removing the class attribute from the writer object after rendering the span begin tag? I don't know ASP though so I could be wrong.

Konrad Rudolph
Unfortunately, the writer object doesn't have a "RemoveAttribute" method or the like. And calling writer.AddAttribute(HtmlTextWriterAttribute.Class, "") actually creates two CLASS attributes in the INPUT tag; one with "btnOrange" as its value and the other with an empty value.
Bullines
+1  A: 

You can do this:

private string _heldCssClass = null;
public override void RenderBeginTag(HtmlTextWriter writer)
{
   writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);   
   writer.RenderBeginTag("span");
   _heldCssClass = this.CssClass;
   this.CssClass = String.Empty;
   base.RenderBeginTag(writer);
}

public override void RenderEndTag(HtmlTextWriter writer)
{
   writer.RenderEndTag();
   base.RenderEndTag(writer);
   this.CssClass = _heldCssClass;
}

The reason why I retain the CssClass property in a private variable between the method invocations is so prevent side effects from occurring during rendering. This may be unimportant in your particular code ("is the CssClass property really that important -after- rendering?") but it is always a good idea to prevent or reduce the impact of side effects such as what the code above exhibits by blanking out the property.

cfeduke
A: 

Instead of invoking the base RenderBegin/RenderEnd methods, which themselves will invoke AddAttributesToRender (thereby adding the class attribute), just render the input tag yourself like you are doing with the span....

deepcode.co.uk