Почему ASP.Net RadioButton и CheckBox отображаются внутри Span? - PullRequest
51 голосов
/ 15 июня 2009

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

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

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

Ответы [ 7 ]

113 голосов
/ 11 ноября 2009

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

Например, вот как добавить класс непосредственно в элемент управления checkbox без чепухи span:

myCheckBoxControl.InputAttributes.Add("class", "myCheckBoxClass")
48 голосов
/ 15 июня 2009

Веб-элементы управления в пространстве имен 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.

5 голосов
/ 15 июня 2009

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

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

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

3 голосов
/ 16 октября 2009

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

См. здесь для примера того, как сделать это со списком переключателей.

Я закончил с этим как 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 для получения адаптера управления по умолчанию в качестве отправной точки.

1 голос
/ 31 декабря 2015

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

0 голосов
/ 22 июня 2013

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


    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
    }

0 голосов
/ 21 ноября 2012

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

function resetChk(ctl, bEnable) { 

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

        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...