129 votes

Comment afficher le texte par défaut "--Sélectionner l'équipe --" dans une boîte combo sur un pageload en WPF ?

Dans une application WPF, dans une application MVP, j'ai une boîte combo, pour laquelle j'affiche les données extraites de la base de données. Avant que les éléments ne soient ajoutés à la liste déroulante, je souhaite afficher le texte par défaut suivant

" -- Sélectionner l'équipe --"

afin qu'il s'affiche lors du chargement de la page et qu'en le sélectionnant, le texte s'efface et les éléments s'affichent.

La sélection des données à partir de la base de données se produit. J'ai besoin d'afficher le texte par défaut jusqu'à ce que l'utilisateur sélectionne un élément dans la liste déroulante.

Veuillez me guider

137voto

Chris Walter Points 721

La méthode la plus simple que j'ai trouvée est la suivante :

<ComboBox Name="MyComboBox"
 IsEditable="True"
 IsReadOnly="True"
 Text="-- Select Team --" />

Vous devrez évidemment ajouter d'autres options, mais c'est probablement la façon la plus simple de procéder.

Cette méthode présente toutefois un inconvénient : si le texte à l'intérieur de la liste déroulante n'est pas modifiable, il reste sélectionnable. Cependant, étant donné la mauvaise qualité et la complexité de toutes les alternatives que j'ai trouvées jusqu'à présent, il s'agit probablement de la meilleure option disponible.

0 votes

Excellente réponse Chris ! J'ajouterais simplement Focusable="True", mais ce n'est qu'un changement cosmétique.

6 votes

Réponse parfaite Chris. Une propriété peut faire une si grande différence :D

8 votes

Focusable="False" IsEditable="True" IsReadOnly="True"

98voto

Tri Q Points 2661

Vous pouvez le faire sans code en utilisant une fonction IValueConverter .

<Grid>
   <ComboBox
       x:Name="comboBox1"
       ItemsSource="{Binding MyItemSource}"  />
   <TextBlock
       Visibility="{Binding SelectedItem, ElementName=comboBox1, Converter={StaticResource NullToVisibilityConverter}}"
       IsHitTestVisible="False"
       Text="... Select Team ..." />
</Grid>

Vous avez ici la classe du convertisseur que vous pouvez réutiliser.

public class NullToVisibilityConverter : IValueConverter
{
    #region Implementation of IValueConverter

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

Enfin, vous devez déclarer votre convertisseur dans une section de ressources.

<Converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />

Où Convertisseurs est l'endroit où vous avez placé la classe de convertisseurs. Voici un exemple :

xmlns:Converters="clr-namespace:MyProject.Resources.Converters"

L'avantage de cette approche est qu'il n'y a pas de répétition de code dans votre code.

0 votes

J'aimerais utiliser ceci, mais il semble que ce ne soit pas autorisé dans les cas où le combobox est l'en-tête d'une grille de données . XAML affiche une erreur indiquant que l'en-tête est déjà défini (ou peut-être qu'il ne peut pas être défini plus d'une fois). Des idées ? Je pense simplement utiliser une option à valeur nulle, qui permettra ensuite une réinitialisation en la sélectionnant, mais cela semble un peu négligé.

1 votes

L'une des principales raisons pour lesquelles il s'agit d'une excellente solution est que pratiquement tous les projets WPF liés à des données utilisent un convertisseur NullToVisibilityConverter, qui est donc déjà présent la plupart du temps - autant l'utiliser !

2 votes

En fait, vous pouvez utiliser un DataTrigger pour éviter même le code du convertisseur ici :)

55voto

HappyNomad Points 1823

J'aime bien la réponse de Tri Q, mais ces convertisseurs de valeur sont pénibles à utiliser. PaulB l'a fait avec un gestionnaire d'événements, mais c'est également inutile. Voici une solution purement XAML :

<ContentControl Content="{Binding YourChoices}">
    <ContentControl.ContentTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox x:Name="cb" ItemsSource="{Binding}"/>
                <TextBlock x:Name="tb" Text="Select Something" IsHitTestVisible="False" Visibility="Hidden"/>
            </Grid>
            <DataTemplate.Triggers>
                <Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
                    <Setter TargetName="tb" Property="Visibility" Value="Visible"/>
                </Trigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ContentControl.ContentTemplate> 
</ContentControl>

41voto

IceForge Points 101

Personne n'a dit qu'une solution purement xaml devait être compliquée. En voici une simple, avec 1 data trigger sur la boîte de texte. Marge et position à volonté

<Grid>
    <ComboBox x:Name="mybox" ItemsSource="{Binding}"/>
    <TextBlock Text="Select Something" IsHitTestVisible="False">
           <TextBlock.Style>
                <Style TargetType="TextBlock">
                      <Setter Property="Visibility" Value="Hidden"/>
                      <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=mybox,Path=SelectedItem}" Value="{x:Null}">
                                  <Setter Property="Visibility" Value="Visible"/>
                             </DataTrigger>
                      </Style.Triggers>
                </Style>
           </TextBlock.Style>
     </TextBlock>
</Grid>

5 votes

J'ai dû déplacer le paramètre "Visibility="Hidden" dans le déclencheur de données. C'est certainement l'approche la plus directe que j'ai vue. Pour la réutilisation, j'ai déplacé le style dans une ressource

0 votes

La réponse de @Mitch IceForce ne fonctionne pas pour moi, qu'as-tu changé pour qu'elle fonctionne ?

1 votes

@Chris Je pense qu'il voulait dire ajouter <Setter Property="Visibility" Value="Hidden"/> à l'extérieur du déclencheur (à l'intérieur du style) et en supprimant Visibility="Hidden" de l'élément de texte proprement dit

29voto

medusa Points 111

Set (jeu de mots) IsEditable="True" sur le ComboBox élément. Cet élément affichera l'élément Text de la propriété ComboBox .

2 votes

C'est la solution la plus simple de toutes.

10 votes

Il modifie cependant l'aspect du contrôle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X