2009-06-15 5 views
50

Spodziewam się następująco:Dlaczego program ASP.Net RadioButton i CheckBox renderuje się w obrębie zakresu?

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

... do renderowania jak ten (z pewnymi atrybutami usuniętymi dla uproszczenia):

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

... gdy w rzeczywistości RadioButton i CheckBox zostanie zapakowany tagiem span, a klasa CSS zostanie tam zastosowana.

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

Czy istnieje ku temu powód i czy istnieje sposób, aby tego uniknąć? To sprawia, selektorów jQuery brzydki, ponieważ nie można złapać wszystkie z nich:

$("input.myClass") 

prawda jest po prostu będzie:

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

... ale to jest brzydkie. Mógłbym napisać własny selektor, ale znowu nie tak elegancko, jak być powinien.

+0

jak tylko $ (". MyClass")? – Hardwareguy

+1

Nie jestem odpowiedzią, ale tylko współczuję - kiedy po raz pierwszy zacząłem pracę na platformie .NET kilka lat temu i używałem JS, aby sprawdzić wartość pola wyboru, spędziłem kilka godzin próbując ustalić, dlaczego moje wartości nie były alarmowanie. Zgadnij co - tagi span. Zawsze zastanawiałem się, dlaczego MS dodało nadmiarowe znaczniki dla radiobutonów i pól wyboru! – Dhana

+0

@Hardwareguy Czasami będzie to zakres, a czasami będzie to wejście. To jest problem. $ ("input.myclass") może być trochę zbyt szczegółowe, ale $ (". myClass") dałoby ci ten sam ból głowy. – Mark

Odpowiedz

42

Elementy sterujące w obszarze nazw System.Web.UI.WebControls mogą wyglądać inaczej w różnych przeglądarkach. Nie można na nich liczyć, zawsze renderując te same elementy. Mogą dodać coś, co według nich jest potrzebne, aby działało w określonej przeglądarce.

Jeśli chcesz mieć jakąkolwiek kontrolę nad tym, jak formanty są renderowane jako html, powinieneś zamiast tego użyć kontrolek w przestrzeni nazw System.Web.UI.HtmlControls. To znaczy:

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

Będą renderowane jako odpowiedni element HTML, bez dodatkowych elementów. Oznacza to oczywiście, że będziesz musiał wziąć odpowiedzialność za zgodność przeglądarki, ponieważ kontrola nie działa. Ponadto te elementy sterujące nie mają wszystkich funkcji kontrolek w przestrzeni nazw WebControls.

+0

Z iloma postbackami się zdaję, myślę, że to byłby ból głowy. Zgadzam się, że powinniśmy używać tych kontrolek domyślnie i wchodzić do WebControls w razie potrzeby. – Mark

+14

Jeśli masz zamiar to zrobić, równie dobrze możesz użyć ASP.Net MVC;) – womp

+5

@Womp Chciałbym, żeby to była opcja. – Mark

5

Każda kontrolka WebControl jest domyślnie renderowana jako znacznik <span> oraz dowolne niestandardowe renderowanie dodawane przez autora kontroli.

Jedną z pierwszych rzeczy, które zwykle robisz, pisząc niestandardowy WebControl, jest nadpisanie właściwości "TagKey" w celu renderowania elementu div lub innego niż span. Domyślną wartością tej właściwości jest HtmlTextWriterTag.Span.

Możesz podklasować elementy pola wyboru i zastąpić właściwość TagKey, aby renderować coś innego, ale musisz uporać się z wprowadzaniem wszystkich pól wyboru w swojej własnej wersji.

+0

Chyba musisz wybrać swoją truciznę. Brzydkie selektory jQuery lub sporadyczne podklasy kontrolne zapewniające spójne renderowanie. Byłbym cool, jeśli _all_ formanty wejściowe renderowane z rozpiętością. Spójność jest w połowie przyzwoitą rzeczą. – Mark

3

Natrafiłem na ten problem i próbowałem go rozwiązać za pomocą adapterów kontrolnych.

Patrz przykład here, aby zapoznać się z przykładem wykonania tej czynności z listą przycisków radiowych.

skończyło się to jako mój 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(" />"); 

    } 
} 

I to dodaje do moich przeglądarek Plik-

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

oczywiście, istnieją pewne wady tego.Wraz z tymi wymienionymi pod adresem the above link tracisz także funkcjonalność, jeśli nie implikujesz wszystkiego (powyższy kod nie pozwala na zaznaczenie przycisku radiowego). Istnieją pewne przyjazne dla CSS adaptery sterujące, ale nie obejmują one sterowania przyciskiem radiowym. Możliwe jest użycie reflektora w celu uzyskania domyślnego adaptera kontrolnego jako punktu wyjścia.

+0

Podoba mi się ta sugestia! Późny komentarz wiem, ale to mi bardzo pomogło dzisiaj! –

104

To również doprowadzało mnie do szaleństwa, dopóki nie znalazłem właściwości inputAttributes.

Na przykład, oto jak dodać klasę bezpośrednio sprawie kontroli pole wyboru bez bzdur Okres:

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

Gdybym mógł, dałbym +100, bo nie jestem w stanie dać +1 :) Dzięki! – k25

+6

Świetne znalezienie pracy. Zwróć też uwagę, że "LabelAttributes" działa odpowiednio do stylu odpowiedniej etykiety Checkbox. – magnattic

+0

To dziwne, ponieważ 'myCheckBoxControl.Attributes.Add' wywoła to samo zachowanie co' myCheckBoxControl.CssClass', gdzie zawija je w znaczniku '', ale 'myCheckBoxControl.InputAttributes.Add' nie będzie - yay! –

0

Znalezione podobnego problemu, napisałem funkcję prostego jQuery oparciu włączyć/pole wyboru Wyłącz i nadrzędną rozpiętość

function resetChk(ctl, bEnable) { 

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

     } 
0

najlepszym sposobem, myślę, jest to:

 

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

do użycia I t w sterowaniu niestandardowym:

 

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

Prosty przycisk radiowy jest często wyświetlany bez rozpiętości. Jeśli ustawisz właściwości CssClass, Style, Enabled, RadioButton będzie renderowany z rozpiętością. Ta niekonsekwencja jest prawdziwym problemem, kiedy muszę manipulować przyciskiem radiowym skryptami po stronie klienta. Zazwyczaj stosuję obojętny CssClass, aby zawsze konsekwentnie renderował rozpiętość.

Powiązane problemy