2010-03-04 13 views
10

Tengo una pregunta de WPF para principiantes.¿Es posible suministrar un convertidor de tipo para un recurso estático en WPF?

imaginar mi control de usuario tiene una declaración de espacio de esta manera:

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

Y tengo los recursos para el control de usuario como esto:

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

Y a continuación, en algún lugar de mi control de usuario que tiene este :

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

Esto causará un error porque Today se define como un recurso entero, pero la propiedad Text espera una cadena. Este ejemplo es artificial, pero con suerte ilustra la pregunta.

La cuestión es que, a menos que mi tipo de recurso coincida exactamente con el tipo de propiedad, ¿hay alguna manera de proporcionar un conversor para mis recursos? Algo así como IValueConverter para enlaces o un convertidor de tipo.

Gracias!

Respuesta

23

Es posible si usa un Enlace. Parece un poco raro, pero esto va a trabajar:

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

Es debido a que el motor de enlace se ha incorporado en la conversión de tipo para los tipos básicos. Además, al usar Binding, si no existe un convertidor incorporado, puede especificar el suyo.

+1

Perfecto, gracias por la información. – Notre

+0

¿Qué pasa si quiere obtener los componentes de color de un StatisResource que es un Color? (Por ejemplo, para cambiar la opacidad del color StaticResource). Hacer lo siguiente no parece funcionar:

+1

No funciona porque solo puede establecer un enlace en un DependencyProperty de un DependencyObject. El color es una estructura. Puede crear su propio objeto envoltorio de color, que es DepdendencyProperty, y expone las propiedades A, R, G, B y Color que son ellos mismos DP. Cambiar cualquiera de las propiedades actualizaría la propiedad Color, y al cambiarla se actualizarían todas las demás. –

4

La respuesta de Abe debería funcionar en la mayoría de las situaciones. Otra opción sería ampliar la clase 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! Esto también es interesante. Gracias Thomas! – Notre

Cuestiones relacionadas