2011-01-26 9 views
12

¿Hay alguna manera de definir un convertidor cuando se usa la extensión DynamicResource? Algo en las líneas deUtilice IValueConverter con DynamicResource?

<RowDefinition Height="{Binding Source={DynamicResource someHeight}, Converter={StaticResource gridLengthConverter}}" /> 

que por desgracia me da el siguiente excpetion:

A 'DynamicResourceExtension' cannot be set on the 'Source' property of type 'Binding'. A 'DynamicResourceExtension' can only be set on a DependencyProperty of a DependencyObject.

Respuesta

3

intentar algo así como que: la extensión

de marcado:

public class DynamicResourceWithConverterExtension : DynamicResourceExtension 
{ 
    public DynamicResourceWithConverterExtension() 
    { 
    } 

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

    public IValueConverter Converter { get; set; } 
    public object ConverterParameter { get; set; } 

    public override object ProvideValue(IServiceProvider provider) 
    { 
     object value = base.ProvideValue(provider); 
     if (value != this && Converter != null) 
     { 
      Type targetType = null; 
      var target = (IProvideValueTarget)provider.GetService(typeof(IProvideValueTarget)); 
      if (target != null) 
      { 
       DependencyProperty targetDp = target.TargetProperty as DependencyProperty; 
       if (targetDp != null) 
       { 
        targetType = targetDp.PropertyType; 
       } 
      } 
      if (targetType != null) 
       return Converter.Convert(value, targetType, ConverterParameter, CultureInfo.CurrentCulture); 
     } 

     return value; 
    } 
} 

XAML :

<RowDefinition Height="{my:DynamicResourceWithConverter someHeight, Converter={StaticResource gridLengthConverter}}" /> 
+0

me sale el siguiente error de compilación: 'Desconocido propiedad 'convertidor' para el tipo 'MS.Internal.Markup.MarkupExtensionParser + UnknownMarkupExtension' ' – bitbonk

+0

buena idea, pero no funciona. Hay una discrepancia: 'ProvideValue' es llamado una vez por el analizador XAML y no debe convertir nada. En su lugar, debe proporcionar a la propiedad de dependencia algo que permita la conversión. – jeromerg

+0

¿Por qué no usó el enfoque de @mkoertgen, considerando que está denegando su artículo? ¿Hay algún tipo de inconveniente? – Dzyann

12

Yo sé que soy muy tarde para esto, pero lo que definitivamente funciona es el uso de un BindingProxy para la DynamicResource como esto

<my:BindingProxy x:Key="someHeightProxy" Data="{DynamicResource someHeight}" /> 

A continuación, aplicar el convertidor al proxy

<RowDefinition Height="{Binding Source={StaticResource someHeightProxy}, Path=Data, Converter={StaticResource gridLengthConverter}}" /> 
+0

¡Este fue un hallazgo increíble! También se puede usar para llegar al DataContext como se describe en el artículo. ¡Ya añadido a nuestro conjunto de herramientas!:) – MarqueIV

+0

Fui una de las personas que originalmente votaron esta respuesta, pero en realidad me acaba de ocurrir una solución aún más simple, que se basa en un concepto de 'proxy' similar, excepto que el proxy se maneja de forma automática y transparente detrás de una ampliación de MarkupExtension. Eche un vistazo a mi publicación sobre este mismo tema ... http://stackoverflow.com/questions/33816511/heres-how-to-create-a-dynamicresourcebinding-that-supports-converters-stringfo – MarqueIV

+0

¡Me gusta eso! Tenga en cuenta que las extensiones de marcado pueden ser difíciles de descubrir para XAML a menos que las mueva a un proyecto/ensamblaje separado. – mkoertgen

1

Me gusta la respuesta de mkoertgen.

Aquí hay un ejemplo adaptado para un proxy IValueConverter en VB.NET que funcionó para mí. Mi recurso "VisibilityConverter" se incluye ahora como DynamicResource y se reenvía con el ConverterProxy "VisibilityConverterProxy".

Uso:

... 
xmlns:binding="clr-namespace:Common.Utilities.ModelViewViewModelInfrastructure.Binding;assembly=Common" 
... 
<ResourceDictionary> 
    <binding:ConverterProxy x:Key="VisibilityConverterProxy" Data="{DynamicResource VisibilityConverter}" /> 
</ResourceDictionary> 
... 
Visibility="{Binding IsReadOnly, Converter={StaticResource VisibilityConverterProxy}}" 

Código:

Imports System.Globalization 

Namespace Utilities.ModelViewViewModelInfrastructure.Binding 

''' <summary> 
''' The ConverterProxy can be used to replace StaticResources with DynamicResources. 
''' The replacement helps to test the xaml classes. See ToolView.xaml for an example 
''' how to use this class. 
''' </summary> 
Public Class ConverterProxy 
    Inherits Freezable 
    Implements IValueConverter 

#Region "ATTRIBUTES" 

    'Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc... 
    Public Shared ReadOnly DataProperty As DependencyProperty = 
           DependencyProperty.Register("Data", GetType(IValueConverter), GetType(ConverterProxy), New UIPropertyMetadata(Nothing)) 

    ''' <summary> 
    ''' The IValueConverter the proxy redirects to 
    ''' </summary> 
    Public Property Data As IValueConverter 
     Get 
      Return CType(GetValue(DataProperty), IValueConverter) 
     End Get 
     Set(value As IValueConverter) 
      SetValue(DataProperty, value) 
     End Set 
    End Property 

#End Region 


#Region "METHODS" 

    Protected Overrides Function CreateInstanceCore() As Freezable 
     Return New ConverterProxy() 
    End Function 

    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.Convert 
     Return Data.Convert(value, targetType, parameter, culture) 
    End Function 

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.ConvertBack 
     Return Data.ConvertBack(value, targetType, parameter, culture) 
    End Function 

#End Region 



End Class 

Espacio de nombres Fin

Cuestiones relacionadas