Отображение пользовательского элемента управления asp.net вне тега формы

У меня возникла проблема с пользовательским элементом управления, отображающим его содержимое (дочерние элементы управления) за пределами тега, что приводит к ошибкам и проблемам во время выполнения. Пытаясь максимально упростить ситуацию, я создал элемент управления ниже, но у него та же проблема. Я пытался наследовать от Control, WebControl и CompositeControl, что привело к той же проблеме. Предполагаю, что есть что-то очевидное, что я делаю неправильно... Спасибо за любую помощь.

using System;
using System.Web.UI.WebControls;

namespace MyControls
{
    public class TestControl : CompositeControl
    {
        protected override void CreateChildControls()
        {
            Controls.Clear();
            Controls.Add(new Button() { Text = "TestControl!" });
            ClearChildViewState();
        }
    }
}

Программное добавление элемента управления приводит к разметке вне тега формы. Добавление элемента управления через разметку работает корректно.

protected void Page_Load(object sender, EventArgs e)
{
    Controls.Add(new TestControl());
}



...
<body>
    <form name="PageForm" method="post" action="default.aspx" id="PageForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTE5MDEwMTE5MWRkg0FopdvLhTPGxHkGm1xCCOVQz6A=" />
</div>

    <div>

    </div>
    </form>
</body>
</html>
<span><input type="submit" name="ctl04$ctl00" value="TestControl!" /></span>

person andleer    schedule 15.02.2009    source источник


Ответы (3)


Добавление элемента управления через свойство Page.Form отобразит кнопку внутри формы.

Page.Form.Controls.Add(new Button() { Text = "TestControl!" });

Однако, поскольку кнопка не содержится в блоке, таком как ‹div>, у вас могут возникнуть проблемы с расположением этой кнопки. Используйте подход ScarletGarden.

person baretta    schedule 15.02.2009
comment
Я согласен, что это будет работать, но это не очень интуитивно понятно, особенно если кто-то другой использует элемент управления и не знает лучше. Почему другие пользовательские элементы управления не требуют такого подхода? Элементы управления.Добавить(новая кнопка()); работает нормально. Мой контроль - нет. Что мне не хватает? - person andleer; 16.02.2009
comment
Чаще всего элементы управления включаются с помощью декларативной разметки, а затем вручную добавляются элементы управления в ControlCollection. Вы можете связать пространство имен MyControls с префиксом тега, а затем использовать em, например: ‹my:TestControl ID=test runat=server /› в противном случае предоставьте дополнительную информацию о своей проблеме. - person baretta; 16.02.2009

Это не имеет ничего общего с вашим пользовательским элементом управления. Ваша проблема вызвана тем, как вы добавляете элемент управления на страницу.

Когда вы вызываете Controls.Add в методе Page_Load вашей страницы, это в основном сокращение для:

Page.Controls.Add(new TestControl());

т. е. вы добавляете элемент управления в конец всей иерархии элементов управления вашей страницы. Когда страница отображается, ваш элемент управления отображается после всех остальных, даже после закрывающего тега </html>.

Если вы хотите, чтобы ваш элемент управления отображался внутри формы, вам нужно вместо этого добавить его в иерархию элементов управления формы:

Form.Controls.Add(new TestControl());

Если вам нужно еще более точное позиционирование, вам нужно поместить placeholder (или div или span и т. д.) на свою страницу в нужное положение и добавить к нему свой контроль, как в ответе ScarletGarden.

person LukeH    schedule 16.02.2009
comment
В порядке. Я определенно был в неправильном направлении. Я предположил, что стандартные элементы управления asp.net работают иначе, чем мои, но они демонстрируют ту же проблему при добавлении в коллекцию Page.Controls. Мое неверное предположение. - person andleer; 16.02.2009

С вашим элементом управления все в порядке, я думаю, у вас возникла проблема с добавлением элемента управления на вашу страницу.

Добавьте placeHolder на свою страницу,

<body>
    <form id="form1" runat="server">
    <div>
        <asp:PlaceHolder ID="placeHolder" runat="server"></asp:PlaceHolder>
    </div>
    </form>
</body>

а затем добавьте свой составной элемент управления в коллекцию элементов управления этого заполнителя следующим образом:

TestControl testCtrl = new TestControl();
placeHolder.Controls.Add(testCtrl);
person Canavar    schedule 15.02.2009
comment
Я думаю, что теоретически это будет работать, но это не делает настраиваемый элемент управления очень универсальным. Конечно, не так, как работают другие пользовательские элементы управления. - person andleer; 16.02.2009
comment
Интересно, как вы добавляете свой элемент управления на свою страницу? вы перетаскиваете в теги формы? - person Canavar; 16.02.2009
comment
Прости. Добавляется программно. Отлично работает при добавлении в разметку. - person andleer; 16.02.2009
comment
Зачем нужно добавлять управление программно? - person Robert C. Barth; 16.02.2009