0
votes

Liaison de soulignement WPF (MVVM)

Existe-t-il un moyen de lier le soulignement ?? J'essaie d'obtenir les résultats suivants:

J'ai VievModel avec une propriété booléenne:
public bool HomeButtonUnderline {get; ensemble; } = false;

Je voudrais alors contrôler cette propriété dans la fonction suivante:

<Button>
<TextBlock TextDecorations="Underline">
</Button>

Je pourrais alors utiliser ce contrôle en XAML:

<Button>
<TextBlock Command="{Binding HomeNavCommand}" Underline="{Binding HomeButtonUnderline}"/> 
</Button>

Le problème est qu'il n'y a pas de propriété 'Underline', à la place elle est gérée par 'TextDecorations':

public void Home() {
//CurrentPage = ApplicationPage.Home;
//HomeButtonForeground = new SolidColorBrush(Colors.White);
HomeButtonUnderline = true;
SettingsButtonUnderline = false;
}

Il existe donc un moyen de contrôler le soulignement en utilisant MVVM ou même sans ??


0 commentaires

3 Réponses :


1
votes

Utilisez un convertisseur pour convertir vos types de modèle (dans ce cas, un booléen) en types d'interface utilisateur (dans ce cas, un TextDecoration).

<Button Command="{Binding HomeNavCommand}">
    <Button.Resources>
        <local:UnderlineConverter x:Key="UnderlineConverter" />
    </Button.Resources>
    <TextBlock TextDecorations="{Binding HomeButtonUnderline, Converter={StaticResource UnderlineConverter}"/> 
</Button>

Et puis utilisez-le dans votre liaison (après avoir créé une ressource dans votre fenêtre, UserControl App.xaml ou partout où vous pensez être le bon endroit; pour cet exemple, je le mets simplement dans les ressources du bouton)

public class UnderlineConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;

        return System.Convert.ToBoolean(value) ? TextDecorations.Underline : null;
    }

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

p>


0 commentaires

2
votes

Vous pouvez utiliser un DataTrigger dans un style pour le TextBlock:

<Button Command="{Binding HomeNavCommand}">
    <TextBlock Text="Home">
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding HomeButtonUnderline}" Value="True">
                        <Setter Property="TextDecorations" Value="Underline"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</Button>


4 commentaires

Merci d'avoir répondu. La solution fonctionne, mais je préfère le convertisseur de valeur pour un code un peu plus propre.


@Yoghurt - En fait, vous êtes légèrement en arrière :). Les DataTriggers sont la voie à suivre. C'est juste une chose ponctuelle. Qu'allez-vous faire lorsque vous devez définir 20 propriétés sur un objet? Créer 20 convertisseurs personnalisés? Heck non!


@SledgeHammer - mais que faire si vous souhaitez lier la propriété de soulignement pour 20 blocs de texte différents, chacun à des propriétés différentes? Ensuite, vous aurez besoin de 20 DataTriggers ou d'un seul convertisseur. Les deux méthodes sont utiles dans la bonne situation - c'est "chevaux pour cours".


@SledgeHammer maintenant que j'ai enfin assez de réputation pour commenter: je ne créerais pas 20 convertisseurs. J'essaierais de créer un convertisseur suffisamment générique (comme BoolToValueConverter) et de créer simplement celui-ci en XAML avec les valeurs dont j'ai besoin (dans ce cas, TextDecorations.Underline pour true et null pour false). Cela ne fonctionne pas toujours, mais c'est souvent le cas. Ce que j'aime à propos des convertisseurs par rapport aux DataTriggers, c'est que les convertisseurs n'encombrent pas autant le XAML (c'est subjectif, je sais). Si je dois définir 20 propriétés en réponse à 1 propriété dans le ViewModel, j'utiliserais certainement un DataTrigger.



0
votes

Bien sûr, une autre façon de gérer cela est que votre modèle de vue soit le bon type pour la vue:

public TextDecorationCollection HomeButtonUnderline { get; set; }

HomeButtonUnderline est déjà orienté GUI, il y a donc probablement du code dans votre viewmodel qui attribue une valeur du modèle, donc il pourrait aussi bien convertir de bool en TextDecorations.Underline .

Cette méthode conserve toute la logique dans le même fichier, contrairement à un convertisseur, bien qu'un convertisseur soit plus réutilisable. Il a également l'avantage d'être facilement testable unitaire (contrairement à un déclencheur de données).


0 commentaires