2009-06-15 14 views
50

Yo esperaría que esto:¿Por qué ASP.Net RadioButton y CheckBox se procesan dentro de un 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" /> 

... para hacer como esto (con algunos atributos eliminadas por razones de simplicidad):

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

... cuando en realidad, el RadioButton y CheckBox envuélvete con una etiqueta span y la clase CSS se aplica allí.

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

¿Hay alguna razón para esto y hay alguna manera de evitarlo? Esto hace que los selectores de jQuery fea ya que no puede atrapar todas ellas con:

$("input.myClass") 

Por supuesto que es sólo va a:

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

... pero eso es feo. Podría escribir mi propio selector, pero una vez más no tan elegante como debería ser.

+0

¿cómo combate solo $ (".myClass")? – Hardwareguy

+1

No fue una respuesta, solo una conmiseración: cuando empecé a trabajar en la plataforma .NET hace unos años y estaba usando JS para descubrir el valor de una casilla de verificación, pasé unas horas tratando de descubrir por qué mis valores no alertando Adivina qué, las etiquetas span. Siempre me he preguntado por qué MS agregó etiquetas redundantes para sus botones de radio y casillas de verificación. – Dhana

+0

@Hardwareguy A veces ese será el lapso y algunas veces será la entrada. Ese es el problema. $ ("input.myclass") podría ser un poco demasiado específico, pero $ (". myClass") le daría el mismo dolor de cabeza. – Mark

Respuesta

42

Los controles web en el espacio de nombres System.Web.UI.WebControls pueden representarse de manera diferente en diferentes navegadores. No puede contar con que rendericen los mismos elementos siempre. Pueden agregar cualquier cosa que consideren necesaria para que funcione en el navegador específico.

Si desea tener control sobre cómo se representan los controles como html, debe usar los controles en el espacio de nombres System.Web.UI.HtmlControls. Es decir:

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

Representan el elemento html correspondiente, sin agregar elementos adicionales. Esto, por supuesto, significa que tendrá que asumir la responsabilidad de la compatibilidad del navegador, ya que el control no lo hace. Además, esos controles no tienen todas las características de los controles en el espacio de nombres WebControls.

+0

Con la cantidad de postales devueltas creo que esto sería más un dolor de cabeza. Estoy de acuerdo en que deberíamos utilizar estos controles por defecto y avanzar a los WebControls cuando sea necesario. – Mark

+14

Si va a hacer esto, también puede usar ASP.Net MVC;) – womp

+5

@womp Me encantaría que fuera una opción. – Mark

5

Cada WebControl se representa de forma predeterminada como una etiqueta <span>, más cualquier representación personalizada que añada el autor de control.

Una de las primeras cosas que suele hacer cuando escribe un WebControl personalizado es anular la propiedad "TagKey" para representar un div, o algo además de un lapso. El valor predeterminado de esta propiedad es HtmlTextWriterTag.Span.

Puede subclasificar los elementos de su casillero y anular la propiedad TagKey para representar otra cosa, pero luego tiene que tratar de hacer todas las casillas de verificación en su propia versión.

+0

Supongo que debes elegir tu veneno. Selectores jQuery feos o controles subclase esporádicos para una representación coherente. Me gustaría que todos los controles de entrada sean procesados ​​con un lapso. La consistencia es una cosa a medias decente. – Mark

3

Me encontré con este problema y trato de resolverlo con los adaptadores de control.

Consulte here para ver un ejemplo de cómo hacer esto en una lista de botones de opción.

terminé con esto como mi 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(" />"); 

    } 
} 

Y esto añadido a mis navegadores Archivo-

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

Por supuesto, hay algunas desventajas a este.Junto con los mencionados en the above link, también pierde funcionalidad si no implementa todo (el código anterior no permite que se marque un botón de opción). Hay algunos adaptadores de control amigables con CSS, pero no cubren el control de botón de radio. Es posible utilizar Reflector para obtener el adaptador de control predeterminado como punto de partida.

+0

¡Me gusta esta sugerencia! Último comentario que sé, ¡pero esto me ayudó mucho hoy! –

104

Esto me estaba volviendo loco hasta que encontré la propiedad inputAttributes.

Por ejemplo, aquí es cómo agregar una clase directamente en el control de casilla de verificación sin el lapso sin sentido:

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

Si pudiera, daría +100, ya que no puedo dar un +1 :) ¡Gracias! – k25

+6

Buen trabajo para encontrar esto. También tenga en cuenta que 'LabelAttributes' funciona de acuerdo con el estilo de la etiqueta Checkbox correspondiente. – magnattic

+0

es extraño porque 'myCheckBoxControl.Attributes.Add' activará el mismo comportamiento que' myCheckBoxControl.CssClass' donde lo envuelve en una etiqueta '', pero 'myCheckBoxControl.InputAttributes.Add' no - ¡yay! –

0

Encontrado problema similar, escribió una simple función basada en jQuery para activar/casilla Desactivar y la duración de los padres

function resetChk(ctl, bEnable) { 

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

     } 
0

la mejor forma en que pienso es esto:

 

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

utilizar i t en el control personalizado:

 

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

El RadioButton normal se representa a menudo sin un intervalo. Si configura CssClass, Style, Enabled properties, RadioButton se renderiza con un span. Esta incoherencia es un verdadero dolor cuando necesito manipular el botón de radio con scripts del lado del cliente. Lo que suelo hacer es aplicar una CssClass ficticia para que siempre represente un lapso constante.

Cuestiones relacionadas