Sam Plus Plus
Sam Plus Plus

Reputation: 4601

Render Control in ControlAdapter

This is some what related to my earlier question posted, but not exactly. I finally was able to get my control adapter to fire, however I cannot get it to work as I expected.

The whole reason I would like to use a control adapter is to add additional markup to system controls such as a RadioButton. I am using another framework that that expect this.

If we assume a RadioButton without any changes would render like

<input id="MainContent_RadioButton1" type="radio" name="ctl00$MainContent$RadioButton1" value="RadioButton1" /><label for="MainContent_RadioButton1">My Radio Button</label>

I would like to change the markup to look like

<div class="wrapper">
<input id="MainContent_RadioButton1" type="radio" name="ctl00$MainContent$RadioButton1" value="RadioButton1" /><label for="MainContent_RadioButton1">My Radio Button</label>
</div>

This is a really simplified example, so I am not looking for suggestions of sub classing my controls, or adding a panel to my page with a class.

In my Page-Init I have

protected void Page_Init(object sender, EventArgs e)
{
  HttpContext.Current.Request.Browser.Adapters["System.Web.UI.WebControls.RadioButton"] =
    "ControlAdapterTest.Controls.ControlAdaptors.RadioButtonAdapter";
}

My Control Adapter looks like

public class RadioButtonAdapter : WebControlAdapter {

    public new RadioButton Control => (RadioButton) base.Control;

    #region Overrides of WebControlAdapter

    protected override void Render(HtmlTextWriter writer)
    {
      base.Render(writer);
    }

    #endregion
  }
}

No adapter

Without using the control adapter my radio buttons obviously render fine.

enter image description here

Adapter

Adding my control adapter and changing nothing else, I get unexpected behavior:

enter image description here

I have tried adding calls to make the base control render such as

  RenderChildren(writer);
  RenderContents(writer);

but I can never seem to get the base to control to render.

Ultimately what I would like to have is something like:

protected override void Render(HtmlTextWriter writer)
{

  writer.WriteBeginTag("div");
  writer.AddAttribute("class", "wrapper");
  //Render existing control
  //Control.RenderControl();
  writer.WriteEndTag("div");

}

My questions is, is this even possible, if so am I doing something obviously wrong. Any suggestions or help would be appreciated.

Upvotes: 1

Views: 1065

Answers (1)

Don
Don

Reputation: 6882

You need to use the ControlAdapter class instead of the WebControlAdapter, see further below. The problem with using the WebControlAdapter is that it renders the control by calling the RenderBeginTag, RenderContents and RenderEndTag. https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.adapters.webcontroladapter%28v=vs.110%29.aspx

However in the case of the checkbox, the RenderContents isn't what generates the contents, instead it is the Render method. And the Render method of the control is executed when using the ControlAdapter class. https://msdn.microsoft.com/en-us/library/system.web.ui.adapters.controladapter%28v=vs.110%29.aspx

public class RadioButtonAdapter : System.Web.UI.Adapters.ControlAdapter {
    protected override void BeginRender(HtmlTextWriter writer) {
        writer.Write("<div class=\"wrapper\">");
        base.BeginRender(writer);
    }
    protected override void EndRender(HtmlTextWriter writer) {
        base.EndRender(writer);
        writer.Write("</div>");
    }
}

Upvotes: 3

Related Questions