2009-08-28 6 views
12

J'écris ma toute première application Silverlight. J'ai une grille de données avec une colonne qui a deux étiquettes, pour les étiquettes, j'utilise un IValueConverter pour formater les données de manière conditionnelle.Transmettez la valeur d'un champ à Silverlight ConverterParameter

est défini en tant que tel "Contenu" de l'étiquette:

Content="{Binding HomeScore, Converter={StaticResource fmtshs}}" 

et

Content="{Binding AwayScore, Converter={StaticResource fmtshs}}" 

La Convertir méthode de mon IValueConverter est tel:

Public Function Convert(
    ByVal value As Object, 
    ByVal targetType As System.Type, 
    ByVal parameter As Object, 
    ByVal culture As System.Globalization.CultureInfo) As Object 
Implements System.Windows.Data.IValueConverter.Convert 

    Dim score As Long = value, other As Long = parameter 

    Return If(score < 0, "", 
     If(score - other > 5, (other + 5).ToString, score.ToString) 
    ) 

End Function 

Alors ce que je vouloir faire est dans le convertisseur pour HomeScore, je veux passer AwayScore à la ConverterParameter, et pour AwayScore je veux passer le HomeScore au convertisseur. Dans le convertisseur pour l'un ou l'autre score je dois être capable de connaître la valeur de l'autre score à des fins de mise en forme.

Mais je ne peux pas comprendre la syntaxe pour lier le ConverterParameter à un autre champ.
J'ai essayé ce qui suit:

Content="{Binding HomeScore, Converter={StaticResource fmtshs}, ConverterParameter=AwayScore}" 
Content="{Binding HomeScore, Converter={StaticResource fmtshs}, ConverterParameter={AwayScore}}" 
Content="{Binding HomeScore, Converter={StaticResource fmtshs}, ConverterParameter={Binding AwayScore}}" 

Mais aucun de ceux qui semblent fonctionner. Comment puis-je passer une valeur de champ à ConverterParameter?

+0

J'ai essayé le simple mais dans le convertisseur il me donne une chaîne de '{Binding SomeOtherProperty}'. Ai-je manqué quelque chose? :(PS. J'utilise Silverlight 3. –

+0

Regardez MultiBind Convertisseurs http://stackoverflow.com/questions/377841/what-should-the-converter-parameter-be-for-this-binding – Rauld

Répondre

6

On dirait que vous essayez de se lier à une ConverterParameter que je crains que vous ne pouvez pas. ConverterParameter ne peut prendre que des valeurs littérales, par exemple ConverterParameter = 'Votre chaîne'

+0

Oui , c'était exactement ce que j'étais/je suis en train de faire – eidylon

+3

Si vous ne l'avez pas encore compris, les guillemets simples sont ce qui vous manque dans le code de votre question – Aligned

2

J'ai eu le même problème, et j'ai dû dormir dessus. Semble le convertisseur obtient "one shot" à obtenir les données - grâce à la valeur de liaison. Donc, faites de la valeur Binding une classe complexe.

Si vous utilisez M-V-VM, vous devriez tout de même mettre en forme des données. J'ai donc rendu la valeur Binding plus difficile en incluant la valeur d'affichage et les autres données nécessaires dans mon convertisseur (créer une classe contenue si vous voulez). Ensuite, j'avais besoin de faire fonctionner le convertisseur plus dur, avec sa limitation de convertir ConverterParameters comme valeurs littérales de type Value, donc je crée un Enum dans mon convertisseur, et je jette le littéral dessus pour plus d'élégance dans ma routine Convert. . Ce que je pourrais alors faire est varier la couleur (pinceau) et l'épaisseur d'une cellule de grille, basé sur la valeur affichée et une autre valeur de seuil (que je vérifie contre).

Le code source est sur mon site de blog, son code Silverlight 3 en utilisant la liaison dans un pseudo mode MV-VM (pas d'injection de dépendance, mais bon - son exemple, non?)

téléchargement à l'adresse: http://www.martymazurik.com/file.axd?file=2010%2f6%2fHighlightGridCell.zip.txt

puis retirez le txt

+0

Je pense que c'est la meilleure approche à ce jour. délègue la responsabilité de la complexité dans l'objet auquel il appartient +1 –

7

Comme vous ne pouvez pas passer quoi que ce soit, mais un littéral dans la ConverterParameter la solution est de passer tout l'objet dans le convertisseur et vous pouvez accéder à toutes ses propriétés à l'intérieur du convertisseur.

Donc, votre code devient (en supposant que votre objet est appelé Match):

Public Function Convert(
    ByVal value As Object, 
    ByVal targetType As System.Type, 
    ByVal parameter As Object, 
    ByVal culture As System.Globalization.CultureInfo) As Object 
Implements System.Windows.Data.IValueConverter.Convert 

    Dim match As Match = value 

    ' Do stuff with match' 

End Function 

(Toutes mes excuses pour le manque de détails dans le code)

Ensuite, votre XAML devient

Content="{Binding Converter={StaticResource fmtshs}}" 

REMARQUE Bien que vous vous liez directement au convertisseur, ce n'est pas le cas. Vous liez le contexte de données sans spécifier un Path de sorte que vous pouvez utiliser l'accès à l'ensemble.

Source

+6

Le problème avec ceci est que si une propriété sur l'objet est mise à jour alors le convertisseur de valeur ne se déclenchera pas – Calanus

+0

Juste pour plus de clarté: @ChrisF, vous n'êtes pas lié à le convertisseur, comme vous l'avez mentionné dans votre NOTE.Vous liez le datacontext actuel (comme Path =.), en utilisant le convertisseur donné. La liaison au convertisseur est un non-sens. –

+0

@ Dercsár - en effet. C'était un raccourci qui, rétrospectivement, prête à confusion. – ChrisF

2

ChrisF a la seule solution que je suis en mesure de venir - Liez l'ensemble de l'objet de données à la propriété du contenu et en utilisant un convertisseur construit pour attendre ce type d'objet analyser les propriétés dont vous avez besoin dans le convertisseur lui-même .

<sdk:DataGridTextColumn Header="Report Name" Binding="{Binding Mode=OneTime, Converter={StaticResource ReportNameDateQuarterConverter}}" /> 


/// <summary> 
/// Gets Exposure Report Name Quarter Number formatted from Report.Date and Report.Name 
/// </summary> 
public class ReportNameDateQuarterConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     string qStr = "Quarter "; 
     if (value != null && value.GetType() == typeof(Report)) 
     { 
      switch (((Report)value).Date.Month) 
      { 
       case 1: 
       case 2: 
       case 3: 
        return qStr + "1 " + ((Report)value).Name; 
       case 4: 
       case 5: 
       case 6: 
        return qStr + "2 " + ((Report)value).Name; 
       case 7: 
       case 8: 
       case 9: 
        return qStr + "3 " + ((Report)value).Name; 
       case 10: 
       case 11: 
       case 12: 
        return qStr + "4 " + ((Report)value).Name; 
       default: 
        return qStr + "? " + ((Report)value).Name; 

      } 
     } 
     return qStr + "? " + ((Report)value).Name; 
    } 

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