Почему мой пользовательский элемент управления ASP.Net отображает два атрибута id на моем первом дочернем элементе управления? - PullRequest
2 голосов
/ 21 октября 2009

Я пишу небольшой пользовательский элемент управления ASP.Net, унаследованный от CompositeControl.Элемент управления - это просто панель, содержащая две подпанели с меткой в ​​каждой подпанели.При отображении в исходном коде HTML я вижу, что первый дочерний элемент управления моего пользовательского элемента управления получает два атрибута id: первый - это идентификатор самого пользовательского элемента управления, а второй - свойство ID, которое я назначаю первому дочернему элементу управления.Почему это происходит?

Код:

[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);
    }
}

Использование на странице ASPX:

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

Вывод HTML:

<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>

Ответы [ 2 ]

4 голосов
/ 21 октября 2009

Вы можете исправить это, полностью удалив метод RenderContents - не заменяйте его ничем. По умолчанию составные элементы управления отображают все свои дочерние элементы управления. Если вы сделаете это, ваш элемент управления выдаст чистую разметку:

<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>

Как вы заметили, виноват метод AddAttributesToRender - это удобный метод, который отображает все атрибуты элемента управления верхнего уровня (независимо от того, является ли текущий контекст элементом управления верхнего уровня или нет). Единственная причина, по которой вы бы это назвали, заключается в том, что вы сами взяли на себя полный контроль над процессом рендеринга и хотите отобразить все атрибуты для элемента управления верхнего уровня в одном выражении.

0 голосов
/ 21 октября 2009

Это идентификатор ASP.NET, назначающий пользовательский элемент управления в целом. Если вы перенесете свой пользовательский элемент управления в элемент Div или Span (в самом коде пользовательского элемента управления, а не в разметке), ему будет присвоен идентификатор вместо вашего первого внутреннего «элемента управления».

Примерно так:

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();
}
...