Подтвердить что ты не робот

Почему ASP.Net RadioButton и CheckBox отображаются внутри Span?

Я бы ожидал этого:

<asp:CheckBox    ID="CheckBox1"    runat="server" CssClass="myClass" />
<asp:RadioButton ID="RadioButton1" runat="server" CssClass="myClass" />
<asp:TextBox     ID="TextBox1"     runat="server" CssClass="myClass" />

..., чтобы сделать это (с некоторыми атрибутами, удаленными для простоты):

<input id="CheckBox1"    type="checkbox" class="myClass" />
<input id="RadioButton1" type="radio"    class="myClass" />
<input id="TextBox1"     type="text"     class="myClass" /> 

... когда на самом деле RadioButton и CheckBox обернуты тегом span, и там применяется класс CSS.

<span class="myClass"><input id="CheckBox1"    type="checkbox" /></span> 
<span class="myClass"><input id="RadioButton1" type="radio"    /></span> 
<input type="text" id="TextBox1" class="myClass" /> 

Есть ли причина для этого и есть ли способ избежать этого? Это делает селектора jQuery уродливыми, так как вы не можете их поймать:

$("input.myClass")

Конечно, он просто собирается:

$("input.myClass, span.myClass input")

... но это уродливо. Я мог бы написать свой собственный селектор, но опять же не такой изящный, как должен быть.

4b9b3361

Ответ 1

Веб-элементы управления в пространстве имен System.Web.UI.WebControls могут отображаться по-разному в разных браузерах. Вы не можете рассчитывать на то, что они всегда будут отображать одни и те же элементы. Они могут добавить все, что, по их мнению, необходимо, чтобы заставить его работать в конкретном браузере.

Если вы хотите иметь какой-либо контроль над тем, как элементы управления отображаются как html, вы должны использовать элементы управления в пространстве имен System.Web.UI.HtmlControls. То есть:

<input type="checkbox" id="CheckBox1" runat="server" class="myClass" />
<input type="radio" name="RadioButton1" runat="server" class="myClass" />
<input type="text" id="TextBox1" runat="server" class="myClass" />

Они будут отображаться как соответствующий элемент html, без добавления дополнительных элементов. Это, конечно же, означает, что вам нужно будет взять на себя ответственность за совместимость с браузером, поскольку контроль не работает. Кроме того, эти элементы управления не имеют всех функций элементов управления в пространстве имен WebControls.

Ответ 2

Это сводило меня с ума, пока не нашло свойство inputAttributes.

Например, вот как добавить класс непосредственно в элементе управления флажком без пробела:

myCheckBoxControl.InputAttributes.Add("class", "myCheckBoxClass")

Ответ 3

Каждый WebControl по умолчанию отображает в качестве тега <span> плюс любой пользовательский рендеринг, который добавляет автор управления.

Одна из первых вещей, которые вы обычно делаете при написании пользовательского WebControl, - это переопределить свойство TagKey для отображения div, или что-то помимо пролета. Значением по умолчанию этого свойства является HtmlTextWriterTag.Span.

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

Ответ 4

Я столкнулся с этой проблемой и попытался решить ее с помощью адаптеров управления.

См. здесь для примера этого в списке радиокнопок.

Я закончил с этим как мой RadioButtonAdaptor -

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

public class RadioButtonAdapter : WebControlAdapter
{
    protected override void Render(HtmlTextWriter writer)
    {
        RadioButton targetControl = this.Control as RadioButton;

        if (targetControl == null)
        {
            base.Render(writer);

            return;
        }

        writer.WriteBeginTag("input");
        writer.WriteAttribute("type", "radio");
        writer.WriteAttribute("name", targetControl.GroupName);
        writer.WriteAttribute("id", targetControl.ClientID);            

        if (targetControl.CssClass.Length > 0)
        {
            writer.WriteAttribute("class", targetControl.CssClass);
        }      

        writer.Write(" />");

    }
}

И это добавлено в мой браузерный файл -

<browser refID="Default">
        <controlAdapters>            
            <adapter controlType="System.Web.UI.WebControls.RadioButton"
               adapterType="RadioButtonAdapter" />
        </controlAdapters>
</browser>

Конечно, есть некоторые недостатки. Наряду с упомянутыми в приведенной выше ссылкой, вы также теряете функциональность, если вы не вникаете в все (приведенный выше код не позволяет использовать переключатель быть проверенным). Есть некоторые дружественные CSS адаптеры, но они не охватывают управление переключателем. Возможно, можно использовать Reflector для получения адаптера управления по умолчанию в качестве начальной точки.

Ответ 5

Обычный RadioButton часто отображается без пролета. Если вы устанавливаете свойства CssClass, Style, Enabled, RadioButton отображается с диапазоном. Эта несогласованность - настоящая боль, когда мне нужно манипулировать переключателем с помощью клиентских сценариев. Обычно я использую фиктивный CssClass, чтобы он всегда отображал промежуток последовательно.

Ответ 6

Нашел аналогичную проблему, написал простую функцию на основе jQuery для включения/отключения флажка и родительского диапазона

function resetChk(ctl, bEnable) { 

            if (bEnable){
                ctl.removeAttr('disabled').parent().removeAttr('disabled');
            }else{
                ctl.attr('disabled', true).parent().attr('disabled', true);
            }

        }

Ответ 7

лучший способ, я думаю, это:


    public class HtmlTextWriterNoSpan : HtmlTextWriter
    {
        public HtmlTextWriterNoSpan(TextWriter textWriter) : base(textWriter)
        { 
        }

        protected override bool OnTagRender(string name, HtmlTextWriterTag key)
        {
            if (name == HtmlTextWriterTag.Span)
            {
                return false;
            }

            return base.OnTagRender(name, key);
        }
    }

чтобы использовать его в пользовательском элементе управления:


    protected override void Render(HtmlTextWriter writer)
    {
        writer = new HtmlTextWriterNoSpan(writer);
        base.Render(writer);
        // HERE MORE CODE
    }