Warum wird mein ASP.Net-Steuerelement macht zwei id auf meiner ersten Kind Kontrolle Attribute?

StackOverflow https://stackoverflow.com/questions/1601039

Frage

Ich schreibe ein kleines ASP.Net-Steuerelement von Composite vererben. Die Steuerung ist nur eine Platte, die zwei Teilfelder mit einem Etikett in jeder Teilplatte. Wenn gemacht, ich in der HTML-Quelle sehe, dass das erste Kind die Kontrolle über meine Custom Controls erhält zwei ID-Attribute - die erste die ID der benutzerdefinierten Kontrolle zu sein selbst und der zweite die ID-Eigenschaft ich das erste Kind Kontrolle zuweisen. Warum ist das passiert?

Code:

[ToolboxData("<{0}:MessageBox runat=server></{0}:MessageBox>")]
public class MessageBox : CompositeControl {

    private Panel _MessageHeaderContainer = null;
    private Label _MessageHeaderLabel = null;
    private Panel _MessageDetailsContainer = null;
    private Label _MessageDetailsLabel = null;

    protected override HtmlTextWriterTag TagKey {
        get {
            return HtmlTextWriterTag.Div;
        }
    }

    protected override void CreateChildControls() {

        // Message header area.
        _MessageHeaderContainer = new Panel();
        _MessageHeaderContainer.ID = "HeaderContainer";
        _MessageHeaderContainer.CssClass = "__MessageBox_Container";
        this.Controls.Add(_MessageHeaderContainer);

        // Message header text.
        _MessageHeaderLabel = new Label();
        _MessageHeaderLabel.ID = "HeaderLabel";
        _MessageHeaderLabel.Text = "[ Header ]";
        _MessageHeaderContainer.Controls.Add(_MessageHeaderLabel);

        // Message details area.
        _MessageDetailsContainer = new Panel();
        _MessageDetailsContainer.ID = "DetailsContainer";
        this.Controls.Add(_MessageDetailsContainer);

        // Message details text.
        _MessageDetailsLabel = new Label();
        _MessageDetailsLabel.ID = "DetailsLabel";
        _MessageDetailsLabel.Text = "[ Details ]";
        _MessageDetailsContainer.Controls.Add(_MessageDetailsLabel);

    }

    protected override void RenderContents(HtmlTextWriter output) {
        AddAttributesToRender(output);

        // Render the box.
        _MessageHeaderContainer.RenderControl(output);
        _MessageDetailsContainer.RenderControl(output);
    }
}

Verwendung in ASPX-Seite:

<cc:MessageBox ID="ctlMessageBox" runat="server" />

HTML-Ausgabe:

<div id="ctl00_ctl00_ctlMessageBox">
    <div id="ctl00_ctl00_ctlMessageBox" id="ctl00_ctl00_ctlMessageBox_HeaderContainer" class="__MessageBox_Container">
        <span id="ctl00_ctl00_ctlMessageBox_HeaderLabel">[ Header ]</span>
    </div><div id="ctl00_ctl00_ctlMessageBox_DetailsContainer">
        <span id="ctl00_ctl00_ctlMessageBox_DetailsLabel">[ Details ]</span>
    </div>
</div>
War es hilfreich?

Lösung

Sie können dieses Problem beheben, indem Sie die RenderContents Methode vollständig zu entfernen - ersetze es nicht mit irgendetwas. Standardmäßig machen Verbundsteuerungen ihre alle untergeordneten Steuerelemente. Wenn Sie das tun, Ihre Steuerung erzeugt saubere Markup:

<div id="test">
    <div id="test_HeaderContainer" class="__MessageBox_Container">
     <span id="test_HeaderLabel">[ Header ]</span>
    </div>
    <div id="test_DetailsContainer">
     <span id="test_DetailsLabel">[ Details ]</span>
    </div>
</div>

Wie Sie bemerkt haben, ist die AddAttributesToRender Methode der Täter - es ist eine bequeme Methode, die alle Top-Level-Steuerung Attribute macht (ob der aktuelle Kontext der Top-Level-Steuerung ist oder nicht). Der einzige Grund, warum Sie das nennen würden, wenn Sie die volle Kontrolle über den Rendering-Prozess wurden unter sich und wollte alle Attribute für die Top-Level-Steuerung in einer einzigen Anweisung machen.

Andere Tipps

Dies ist die ID ASP.NET die Custom Control als Ganzes zuweist. Wenn Sie Ihren Custom Control in einem Div oder Span wickeln (im Code Custom Control selbst, nicht im Markup) wird die ID an, dass anstelle des ersten inneren „Kontrolle“ zugeordnet werden.

So etwas wie folgt aus:

protected override void Render(HtmlTextWriter writer)
{
  AddAttributesToRender(writer);

  //must render tag or first inner control will get two IDs
  writer.RenderBeginTag(HtmlTextWriterTag.Span);

  //render child controls here...

  writer.RenderEndTag();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top