はい、誰得(俺得)情報ですね。
たとえば、PanelコントロールのGroupingTextプロパティに何か設定しておくと、出力されるHTMLは<fieldset>と<legend>になります。で、その<legend>にclassを付けたいなと思ったとしても、ふつうのPanel
コントロールだと手段がありません。Panel
を継承して拡張すればいいんですが、そうしたくない特殊な事情があった場合はどうしましょう。
JavaScriptでやれ。はい、もっともですね。でもまあここではそういう手段はとらないことにします。いまどきWeb Formsを使ってるようなとこにはいろいろ事情があるんです。
そんな時はコントロールアダプターが使えます。コントロールアダプターを使う場合、普通はブラウザー定義ファイルに書いておくのですが、コードから設定することもできなくはないです。
public class LegendTagModifier : Control
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Context != null && !DesignMode)
{
var dict = Context.Request.Browser.Adapters;
var panelName = typeof(Panel).FullName;
if(!dict.Contains(panelName))
{
dict.Add(panelName, typeof(PanelAdapter).FullName);
}
}
}
public class PanelAdapter : WebControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
if (!string.IsNullOrEmpty(((Panel)Control).GroupingText))
{
writer = new LegendTagHtmlTextWriter(writer);
}
base.Render(writer);
}
}
public class LegendTagHtmlTextWriter : HtmlTextWriter
{
public LegendTagHtmlTextWriter(HtmlTextWriter writer)
: base(writer)
{
this.Indent = writer.Indent;
this.NewLine = writer.NewLine;
}
public override void RenderBeginTag(HtmlTextWriterTag tagKey)
{
if (tagKey == HtmlTextWriterTag.Legend)
{
// <legend class="foo bar"></legend>
this.AddAttribute(HtmlTextWriterAttribute.Class, "foo bar");
}
base.RenderBeginTag(tagKey);
}
}
}
上のLegendTagModifier
カスタムコントロールをaspxに放り込んでおくと、Panel
が<legend>を出力する時だけ介入できます。