2010-01-20 9 views
5

Ich verwende derzeit eine GridView und möchte die CssClass für die Zeile abhängig von einer Eigenschaft des Objekts festlegen an die die Reihe gebunden wird.Wie Sie den RowStyle einer GridView-Zeile abhängig von einer Eigenschaft des Objekts festlegen, an das die Zeile gebunden ist

habe ich versucht, die folgenden, aber es funktioniert nicht (siehe Kommentare):

<asp:GridView id="searchResultsGrid" runat="server" AllowPaging="true" PageSize="20" AutoGenerateColumns="false"> 

<!-- The following line doesn't work because apparently "Code blocks 
aren't allowed in this context: --> 
    <RowStyle CssClass="<%#IIF(DataBinder.Eval(Container.DataItem,"NeedsAttention","red","") %> 

    <Columns> 
<!--............--> 
    </Columns> 
</asp:GridView> 

Jetzt konnte ich einfach die RowDataBound Veranstaltung Gridhandhaben und die CSS-Klasse der Reihe dort ändern ... aber ich bin Es wird versucht, eine klare Trennung zwischen der Benutzeroberfläche und den Seiten-/Geschäftslogikschichten beizubehalten.

Ich habe keine Ahnung, wie dies zu erreichen ist und ich freue mich auf irgendwelche Vorschläge zu hören.

Danke,

-Frinny

Antwort

4

Sie können dies in deklarativen Markup nicht.

Fast alle deklarativen Eigenschaften von GridView (einschließlich GridView.RowStyle) sind Einstellungen auf Grid-Ebene und nicht auf Zeilenebene. Abgesehen von TemplateFields sind sie keine Datencontainer, daher haben sie keinen Zugriff auf die Daten in ihren Zeilen.

Wenn Sie diese Logik in der ASPX-Vorlage behalten möchten, Ihre einzige wirkliche Option ist Vorlagenfelder zu verwenden und deren Inhalt zu manipulieren:

<asp:TemplateField> 
    <ItemTemplate> 
     <span class="<%# ((string)Eval("property3")) == "NeedsAttention" ? "red" : string.Empty %>"> 
      <%# Eval("property1") %> 
     </span> 
    </ItemTemplate>       
</asp:TemplateField> 

Je nachdem, was Sie tun wollen, kann dies unangenehm sein - Sie haben keinen Zugriff auf das enthaltende <td> (oder <tr> für diese Angelegenheit) und Sie müssen die Formatierung für jede Zelle wiederholen.

Die GridView Klasse geht um viele Längen, um die Details von HTML und Styling von Ihnen zu verbergen. Nach allem, was Sie könnte erstellen Sie eine GridViewcontrol adapter, die nicht einmal als HTML-Tabellen rendern würde. (Unwahrscheinlich, dass das sein kann.)

Also, obwohl Sie versuchen, es zu vermeiden, sind Sie wahrscheinlich am besten damit in einem OnRowDataBound Handler - oder verwenden Sie eine Repeater (wenn das angemessen ist).

+0

Ja, ich dachte auch darüber nach, aber ich war nicht glücklich mit der Tatsache, dass ich dies für jedes TemplateField und BoundField in der Reihe tun müsste. Es wird peinlich sein. Vielleicht beiße ich einfach in den sauren Apfel und kümmere mich um das OnRowBound-Event. So viel, um meine Schichten getrennt zu halten. – Frinavale

+0

Danke Jeff.So enttäuschend diese Antwort auch ist, Sie haben zumindest bestätigt, dass dies unmöglich ist. – Frinavale

+0

Sie wetten - und es tut mir leid, die schlechten Nachrichten zu bringen. Die GridView ist was es ist und hat viele Enttäuschungen hervorgebracht; Ich versuche es zu vermeiden, wenn ich kann. Wenn seine Vorteile (wie sie sind) unwiderstehlich sind, beiße ich auch in die Kugel. –

2

Ich weiß, es war fast ein Jahr, aber wenn jemand anderes dies versucht, versuchen Sie die GridView Unterklasse.

public class GridViewCSSRowBindable : GridView 
{ 
    public string DataFieldRowCSSClass { get; set; } 
    protected override void OnRowDataBound(GridViewRowEventArgs e) 
    { 
    base.OnRowDataBound(e); 
    if (!string.IsNullOrEmpty(DataFieldRowCSSClass)) 
    { 
     //This will throw an exception if the property does not exist on the data item: 
     string cssClassString = DataBinder.Eval(e.Row.DataItem, DataFieldRowCSSClass) as string; 
     if (!string.IsNullOrEmpty(cssClassString)) 
     { 
     string sep = string.IsNullOrEmpty(e.Row.CssClass) ? string.Empty : " "; 
     e.Row.CssClass += sep + cssClassString; 
     } 
    } 
    } 
} 

Und dann in Ihrer Seite:

<custom:GridViewCSSRowBindable ID="gvExample" runat="server" DataFieldRowCSSClass="RowCSS"> 
</custom:GridViewCSSRowBindable> 

Die Objekte auf dieses Beispiel Gridview gebunden zu sein um eine öffentliche Zeichenfolge RowCSS Eigenschaft.

Wenn Sie zuvor keine geerbten Steuerelemente verwendet haben, müssen Sie möglicherweise nachsehen, wie Sie dies in Ihrem Projekt einrichten können.

+0

Da es sich bei dem GridView.RowDataBound um ein öffentliches Ereignis handelt, können Sie in einem Ereignishandler etwas Ähnliches tun. Die Verwendung eines Event-Handlers kann nützlich sein, wenn Sie die GridView aus irgendeinem Grund nicht unterklassifizieren können. – Joel

+0

Ich erinnere mich nicht einmal daran, diese Frage zu posten! Aber der Punkt war, dass ich keinen Code hinter dem Stil haben wollte. Ich wollte meine UI-Inhalte im ASP-Code behalten und somit das OnRowDataBound-Ereignis vermeiden. Also, während Ihre Lösung funktioniert, suchte ich nach einer alternativen Möglichkeit (ohne den Code dahinter zu verwenden). Danke für Ihre Antwort. Dies ist hilfreich für diejenigen, die das OnRowBound-Ereignis nicht kennen. – Frinavale

0
foreach (TableCell gvc in gvRowPhistry.Cells) 
{ 
    gvc.ForeColor = System.Drawing.Color.Blue; 
} 
+2

Ein wenig mehr Erklärung könnte den anderen Programmierern helfen zu verstehen, wie der Code funktioniert. – Daenarys

Verwandte Themen