ASP.NET HTML code generation, two approaches I was asked to give more context. So here we go.

We want to create some HTML in code behind to add an "add" and a "refresh" button to a grid view header column. Approach #1 does this using string concatination to produce the necessary HTML, whereas approach #2 uses .NET objects to create exactly the same HTML.

This time I'm posting the complete classes:

Approach #1

class AddBtnTemplate : ITemplate {
    StatRefTimeGrid Parent;
    public AddBtnTemplate(StatRefTimeGrid parent) {
        Parent = parent;
    }
    public void InstantiateIn(Control container) {
        GridViewHeaderTemplateContainer ctr = (GridViewHeaderTemplateContainer)container;
        string html = "&lt;div style='width:150px'&gt;";
        if (Parent.MayEdit)
            html += string.Format("&lt;img alt='{0}' title='{0}' src='Img/add18d.png' style='cursor: pointer' onclick='StatRefTimeGrid.addRow()' /&gt;", Texts.CompValue.AddRefTime[Parent.Parent.State.LangIdx]);
        if (ctr.Grid.VisibleRowCount &gt; 1)
            html += string.Format("&lt;img alt='{0}' title='{0}' src='Img/refresh18d.png' style='cursor: pointer' onclick='StatRefTimeGrid.refresh()' /&gt;", Texts.CompValue.RefreshRefTimeGrid[Parent.Parent.State.LangIdx]);
        html += "&lt;/div&gt;";
        ctr.Controls.Add(new LiteralControl(html));
    }
}


Approach #2

private class AddBtnTemplate : ITemplate {
    private readonly StatRefTimeGrid mParent;
    public AddBtnTemplate(StatRefTimeGrid parent) {
        mParent = parent;
    }
    public void InstantiateIn(Control container) {
        GridViewHeaderTemplateContainer templateContainer = (GridViewHeaderTemplateContainer)container;

        HtmlGenericControl div = new HtmlGenericControl("div") {
            Style = {[HtmlTextWriterStyle.Width] = "150px"},
        };
        if (mParent.MayEdit) {
            AddNewImage(div, Texts.CompValue.AddRefTime[mParent.Parent.State.LangIdx], "~/Img/add18d.png", "StatRefTimeGrid.addRow()");
        }
        if (templateContainer.Grid.VisibleRowCount &gt; 1) {
            AddNewImage(div, Texts.CompValue.RefreshRefTimeGrid[mParent.Parent.State.LangIdx], "~/Img/refresh18d.png", "StatRefTimeGrid.refresh()");
        }

        templateContainer.Controls.Add(div);
    }
    private void AddNewImage(HtmlGenericControl div, string altText, string imageUrl, string onClick) {
        div.Controls.Add(new Image {
            AlternateText = altText,
            ToolTip = altText,
            ImageUrl = imageUrl,
            Attributes = {
                ["onclick"] = onClick,
            },
            Style = {
                [HtmlTextWriterStyle.Cursor] = "pointer",
                [HtmlTextWriterStyle.Position] = "relative",
                [HtmlTextWriterStyle.Top] = "3px",
            },
        });
    }
}


I'm looking for arguments for or against either solution. What do you think?
Second approach is better, according to the rule: do not repeat the code!

Don't use '+=' to join string, in your case better to use StringBuilder:

var sb = new StringBuilder();
sb.Append();
...
sb.Appden();
...
return sb.ToString();


I think this is better way, StringBuilder is made for this.
You can refactor this code better little more :-)