2010-11-04 19 views
0

J'ai une liaison avec Image.Source et TextBlocks. J'ai aussi mes propres classes de convertisseurs.Convertisseur conditionnel WPF

<conv:StatusConvertor x:Key="statusConvertor"></conv:StatusConvertor> 
<conv:ImageConvertor x:Key="imageConvertor"></conv:ImageConvertor> 

Par exemple:

<Image Source="{Binding Value.profilePhoto, Converter={StaticResource imageConvertor}}" Margin="4,4,4,2"/> 

<TextBlock Name="tbStatus" Text="{Binding Value.status,Converter={StaticResource statusConvertor}}" Grid.Column="0" Grid.Row="2" Margin="2,2,2,2" FontSize="11" FontWeight="Normal"></TextBlock> 

Je veux condition définie pour ImageConvertor, par exemple:

IF tbStatus.Text=="0" 
THEN use imageConvertor on Image.Source 

Il est possible que cette écriture en XAML, peut-être en classe convertisseur?

Répondre

0

Je ne pense pas que ce soit possible en XAML. Je suis assez sûr qu'il est impossible de faire (comme c'est) dans le convertisseur parce que vous n'avez pas accès à l'expéditeur (ici un TextBlock) à l'intérieur.

EDIT: vous pouvez le faire avec un convertisseur à plusieurs valeurs, car vous avez besoin de OneWay Binding. Les convertisseurs multivaleurs sont difficiles à configurer avec une liaison TwoWay (lorsque vous avez besoin de la méthode ConvertBack). Ce que je voudrais faire serait de déclarer deux images (une avec pour chaque valeur de votre TextBlock: 0 et autre) et lier la visibilité à la valeur Textblock de texte (ou directement à Value.status).

+0

En fait, c'est possible - voir ma réponse. –

+0

Mon mauvais. Je suis habitué à TwoWay Binding et avec eux, vous avez besoin de la méthode ConvertBack qui est très difficile à implémenter dans une multi-liaison (vous devez retourner un tableau d'objets à partir d'une seule donnée). –

4

Au lieu de faire votre ImageConverter un IValueConverter, faire un IMultiValueConverter:

<Image Margin="4,4,4,2"> 
    <Image.Source> 
     <MultiBinding Converter="{StaticResource imageConvertor}"> 
      <Binding Path="Value.profilePhoto" /> 
      <Binding Path="Value.status" /> 
     </MultiBinding> 
    </Image.Source> 
</Image> 

A IMultiValueConverter est identique à un IValueConverter, sauf qu'il passe un tableau d'objets au lieu d'une seule valeur de l'objet.

public object Convert(object[] values, 
         Type targetType, object parameter, CultureInfo culture) 
{ 
    // Use your converter code from before, but add a check for the Status value 
    // as well 
    string path = values[0].ToString(); 
    int status = Int32.Parse(values[1].ToString(); 

    if (status == 0) 
     return newImageSource; 

    return DependencyProperty.UnsetValue; 
} 

Voici est difficile pour moi de deviner la conception de votre convertisseur de courant, mais cela vous donne une idée approximative sur ce qu'il faut faire. Je suggère de votre question que si le statut n'est pas 0, vous ne voulez pas que votre convertisseur retourne quelque chose - d'où le DependencyProperty.UnsetValue.

+2

Cela fonctionne principalement ... Mais si le convertisseur renvoie une image une fois, Binding.DoNothing ne remplacera pas ce comportement. Au lieu de cela, il devrait retourner DependencyProperty.UnsetValue. En outre, il doit renvoyer un ImageSource, car il s'agit du type de propriété de la propriété Image.Source. –

+0

Dûment noté - J'ai mis à jour ma réponse pour rendre la valeur de retour légèrement plus claire, et apporter la modification correcte à UnsetValue (en utilisant trop de MVVM et pas assez de convertisseurs récemment). :) –

0

Cela ne répond pas spécifiquement à la question, mais j'ai réussi à résoudre mon problème en utilisant cette question comme un guide, donc je pensais que cela pourrait aider les futurs chercheurs. Il pourrait probablement être étendu plus loin pour résoudre la question originale avec un peu plus de travail.

J'essayais de trouver un moyen d'évaluer une expression IF-conditionnelle dans XAML et voulait combiner la puissance d'une expression Binding et un MarkupExtension. En utilisant l'idée d'un convertisseur, j'ai réussi à créer un ConditionalMarkupConverter. Cela a deux propriétés pour spécifier les valeurs à renvoyer lorsqu'une expression de liaison est évaluée à true ou false et puisqu'il s'agit d'un convertisseur, il peut être facilement ajouté à une expression de liaison.

Converter

public sealed class ConditionalMarkupConverter : MarkupExtension, IValueConverter 
{ 
    public object TrueValue { get; set; } 
    public object FalseValue { get; set; } 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is bool && (bool)value) 
     { 
      // The given value has evaluated to true, so return the true value 
      return TrueValue; 
     } 

     // If we get here, the given value does not evaluate to true, so default to the false value 
     return FalseValue; 
    } 

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

public override object ProvideValue(IServiceProvider serviceProvider) 
{ 
    return this; 
} 

XAML

<TextBlock Text="{Binding IsActive, Converter={converters:ConditionalMarkupConverter TrueValue=Active, FalseValue=Inactive}}" /> 

Dans cet exemple, le TextBlock se lie à une propriété booléenne appelée IsActive et le convertisseur retourne alors la chaîne "active" lorsque IsActive est true ou "Inactif" lorsque IsActive est false.