2010-03-04 23 views
10

J'ai une question WPF débutant.Est-il possible de fournir un convertisseur de type pour une ressource statique dans WPF?

Imaginez mon contrôle utilisateur a une déclaration d'espace de noms comme ceci:

xmlns:system="clr-namespace:System;assembly=mscorlib" 

Et j'avoir des ressources pour le contrôle de l'utilisateur comme ceci:

<UserControl.Resources> 
    <system:Int32 x:Key="Today">32</system:Int32> 
</UserControl.Resources> 

Et puis quelque part dans mon contrôle utilisateur Je possède ce :

<TextBlock Text="{StaticResource Today}"/> 

Cela provoquera une erreur car Today est défini comme une ressource entière, mais la propriété Text attend une chaîne. Cet exemple est artificiel, mais nous espérons qu'il illustre la question.

La question est, à court de faire correspondre exactement mon type de ressource au type de propriété, est-il un moyen pour moi de fournir un convertisseur pour mes ressources? Quelque chose comme IValueConverter pour les liaisons ou un convertisseur de type.

Merci!

Répondre

23

Il est possible d'utiliser une liaison. Il semble un peu bizarre, mais cela fonctionne réellement:

<TextBlock Text="{Binding Source={StaticResource Today}}" /> 

Il est parce que le moteur de liaison a intégré la conversion de type pour les types de base. En outre, en utilisant la liaison, si un convertisseur intégré n'existe pas, vous pouvez spécifier le vôtre.

+1

Parfait, merci pour l'information! – Notre

+0

Et si vous vouliez obtenir les composants de couleur d'un StatisResource qui est une couleur? (Par exemple, pour modifier l'opacité de la couleur StaticResource.) L'opération suivante ne semble pas fonctionner:

+1

Cela ne fonctionne pas car vous ne pouvez définir qu'une liaison sur un DependencyProperty d'un DependencyObject. La couleur est une structure Vous pouvez créer votre propre objet wrapper de couleur, DepdendencyProperty, et exposer les propriétés A, R, G, B et Color qui sont elles-mêmes des DP. La modification de l'une des propriétés mettrait à jour la propriété Color, et sa modification mettrait à jour tous les autres. –

4

La réponse d'Abe devrait fonctionner dans la plupart des situations. Une autre option serait d'étendre la classe StaticResourceExtension:

public class MyStaticResourceExtension : StaticResourceExtension 
{ 
    public IValueConverter Converter { get; set; } 
    public object ConverterParameter { get; set; } 

    public MyStaticResourceExtension() 
    { 
    } 

    public MyStaticResourceExtension(object resourceKey) 
     : base(resourceKey) 
    { 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     object value = base.ProvideValue(serviceProvider); 
     if (Converter != null) 
     { 
      Type targetType = typeof(object); 
      IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; 
      if (target != null) 
      { 
       DependencyProperty dp = target.TargetProperty as DependencyProperty; 
       if (dp != null) 
       { 
        targetType = dp.PropertyType; 
       } 
       else 
       { 
        PropertyInfo pi = target.TargetProperty as PropertyInfo; 
        if (pi != null) 
        { 
         targetType = pi.PropertyType; 
        } 
       } 
      } 
      value = Converter.Convert(value, targetType, ConverterParameter, CultureInfo.CurrentCulture); 
     } 
     return value; 
    } 
} 
+0

Oh! C'est intéressant aussi. Merci Thomas! – Notre