Changement couleur texte cell ListView/GridView [Résolu]

Signaler
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
-
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
-
Bonjour le Forum,

vb.net - wpf - changement couleur de texte dans cellule d'un ListView/GridView

Je recherche la méthode pour automatiser la colorisation du texte de cellule d'un GridView en fonction de son contenu :
- Vert si contenu = OK;
- Rouge si contenu = NOK.

Dans la déclaration du xaml, en implicite, j'ai forcé la couleur verte pour le texte de la cellule.

xaml:
<ListView Name="ListViewPoller" 
          Height="402" Margin="325,252,0,0" 
          HorizontalAlignment="Left" VerticalAlignment="Top" Width="607">
    <ListView.View>
         <GridView>
   
             <GridViewColumn Header="Hosts présents dans le fichier référentiel" Width="300">
                 <GridViewColumn.CellTemplate>
                     <DataTemplate>
                         <TextBlock Text="{Binding Host}" Margin="40,0,0,0"/>
                     </DataTemplate>
                 </GridViewColumn.CellTemplate>
             </GridViewColumn> 
    
             <GridViewColumn Header="Hosts présents dans le fichier export" Width="200">
                 <GridViewColumn.CellTemplate>
                     <DataTemplate>
                         <TextBlock Text="{Binding Exist}" Foreground="Green" Margin="80,0,0,0"/>
                     </DataTemplate>
                  </GridViewColumn.CellTemplate>
             </GridViewColumn>
    
             <GridViewColumn Header="Contrat" Width="100">
                 <GridViewColumn.CellTemplate>
                     <DataTemplate>
                         <TextBlock Text="{Binding Contract}" Margin="30,0,0,0"/>
                     </DataTemplate>
                 </GridViewColumn.CellTemplate>
            </GridViewColumn>
   
         </GridView>
    </ListView.View>
</ListView>


vb:
For Each elem In pollers.Where(Function(x) x.Poller = poller)
    ' NewList contient les hosts du fichier export
    Dim checkhostexport = newList.Where(Function(x) x.ToString = elem.Host)

    Select Case checkhostexport.Count
        Case 1 ' host trouvé dans le fichier export
            itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                               .Exist = "OK",
                                               .Contract = elem.Customer})
       Case Else ' host non trouvé dans le fichier export
            itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                               .Exist = "NOK",
                                               .Contract = elem.Customer})
    End Select
Next

' Chargement de la ListView
With ListViewPoller
     .ItemsSource = itemsPoller
     .Items.Refresh()
End With


Dans ce code, le texte "NOK" s'affiche en couleur verte.
Mon souhait, c'est de le mettre en couleur rouge !!!

Suite recherches, il est apparemment possible de mettre cette condition dans le "Cell Template" du xaml,
mais je n'ai pas trouvé d'exemples/explications.

Merci pour votre temps passé à me lire et de vos suggestions.

jean-marc

7 réponses

Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
420
Bonsoir,
je n'ai pas regardé en détails et encore moins testé, mais dans ces cas là, en général il y a 2 options:
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
25
Bonsoir Whismeril,

Merci de cette réponse aussi rapide.
Je vais lire tes liens proposés et te tiens au courant de mon avancement.

Bonne soirée.

jean-marc
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
25
Whismeril,

Encore un grand merci pour tes conseils.

Pour le lien "http://www.wpf-tutorial.com", je me l'étais déjà mis en favori depuis ma récente initiation au xaml/wpf,
mais pas évident d'y trouver sa problématique.

J'ai donc effectué les modifs suivantes :

Dans la classe "Poller", j'ai déclaré en booléan la variable "Exist":
Public Class Poller
    Public Property Host As String
    Public Property Exist As Boolean
    Public Property Contract As String
End Class


Dans le xaml, j'ai mis:
                        <GridViewColumn Header="Hosts présents dans le fichier export" Width="200">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock HorizontalAlignment="Center" Margin="80,0,0,0">
                                        <TextBlock.Style>
                                            <Style TargetType="TextBlock">
                                                <Setter Property="Text" Value="NOK" />
                                                <Setter Property="Foreground" Value="Red" />
                                                <Style.Triggers>
                                                    <DataTrigger Binding="{Binding Exist}" Value="True">
                                                        <Setter Property="Text" Value="OK" />
                                                        <Setter Property="Foreground" Value="Green" />
                                                    </DataTrigger>
                                                </Style.Triggers>
                                            </Style>
                                        </TextBlock.Style>
                                    </TextBlock>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>

et
        For Each elem In pollers.Where(Function(x) x.Poller = poller)
            Dim checkhostexport = newList.Where(Function(x) x.ToString = elem.Host)

            Select Case checkhostexport.Count
                Case 1
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = True,
                                                       .Contract = elem.Customer})
                Case Else
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = False,
                                                       .Contract = elem.Customer})
            End Select
        Next


et résultat concluant !!!

jean-marc
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
420
Parfait,
cependant, je ne pense pas (toujours pas fait de test...) qu'il était nécessaire de changer ta classe

<DataTrigger Binding="{Binding Exist}" Value="OK"
devrait marcher aussi.
Evidement, il faut être sûr que OK ne soit pas écrit oK Ok ou ok.


Ton code behind m'interroge
        For Each elem In pollers.Where(Function(x) x.Poller = poller)
            Dim checkhostexport = newList.Where(Function(x) x.ToString = elem.Host)

            Select Case checkhostexport.Count
                Case 1
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = True,
                                                       .Contract = elem.Customer})
                Case Else 'Else sous entend que 0, 2, 1000... conditionne pour que Exist soit false, ça ne me parait pas très logique. 0 d'accord, 2 10 ou 1000, dans ce cas Exist est mal nommé
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = False,
                                                       .Contract = elem.Customer})
            End Select
        Next


En supposant qu'Exist est vrai si il y a au moins 1 x.ToString = elem.Host, tu peux faire un truc comme ça (tapé de tête)
For Each elem In pollers.Where(Function(x) x.Poller = poller)
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = newList.Any(Function(x) x.ToString = elem.Host),
                                                       .Contract = elem.Customer})
            Next

Ou même un truc comme ça
itemsPoller = pollers.Where(Function(x) x.Poller = poller).Select(Function(elem) New Poller() With {.Host = elem.Host,
                                                       .Exist = newList.Any(Function(x) x.ToString = elem.Host),
                                                       .Contract = elem.Customer}).ToList()
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
25
Bonjour Whismeril,

Explications:
Je parcours un référentiel avec tous les hosts supervisés pour y extraire 3 informations:
        Dim pollers = (
            From row In datapollers.AsEnumerable()
            Select New SheetHosts With {
                .Customer = row.Field(Of String)("Contrat"),
                .Host = row.Field(Of String)("Host"),
                .Poller = row.Field(Of String)("Poller")
            }).ToList

Un host est unique et est supervisé par un poller.
Un poller supervise x hosts, avec contrats éventuellement différents.

Je récupère x fichiers "export_<nomdupoller>" qui comporte tous les hosts supervisés par <nomdupoller>.
J'ai créé une listbox avec tous les fichiers "export_<nomdupoller>".

A partir du fichier export sélectionné dans la listbox, je créé une collection.
        ' Extraction nom des hosts dans le fichier export
        Dim item As Object = ListBoxFilesPoller.SelectedItem
        Dim poller As String = item.ToString.Substring(27).Replace(".txt", String.Empty)
        Dim linesexport As List(Of String) = System.IO.File.ReadAllLines(pathroot & "export_" & poller & ".txt").ToList
        Dim newList As List(Of String) = New List(Of String)()
        Dim pattern As String = "(?<host>^[a-zA-Z0-9-_]+)"

        For Each line In linesexport
            For Each m As Match In Regex.Matches(line.ToString, pattern)
                If newList.Contains(m.Value) = False Then
                    newList.Add(m.Value)
                End If
            Next
        Next
        newList.Sort()

Actuellement, ces fichiers export peuvent contenir certaines erreurs (il manque des hosts).
Mon but est de déceler ces erreurs.

D'où
- parcours du référentiel et sélection du poller souhaité
- test (checkhostexport) si le host se trouve dans le fichier export
-> si oui, "exist = True"
-> si non, "exist = False"
        For Each elem In pollers.Where(Function(x) x.Poller = poller)
            Dim checkhostexport = newList.Where(Function(x) x.ToString = elem.Host)

            Select Case checkhostexport.Count
                Case 1
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = True,
                                                       .Contract = elem.Customer})
                Case Else
                    itemsPoller.Add(New Poller() With {.Host = elem.Host,
                                                       .Exist = False,
                                                       .Contract = elem.Customer})
            End Select
        Next

        ' Chargement de la ListView
        With ListViewPoller
            .ItemsSource = itemsPoller
            .Items.Refresh()
        End With




Bon dimanche,

jean-marc
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
420
Donc les 2 codes que je t'ai proposé devraient fonctionner aussi (sauf erreur de frappe....)
Messages postés
1854
Date d'inscription
jeudi 23 mai 2002
Statut
Membre
Dernière intervention
24 juin 2018
25
Je viens de tester ta 2ème proposition.
Résultat conforme !!!

Encore un grand merci Whismeril.

jean-marc
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
420
De rien