2011-01-26 18 views
12

Czy istnieje sposób zdefiniowania konwertera podczas korzystania z rozszerzenia DynamicResource? Coś w liniachUżyj IValueConverter z DynamicResource?

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

co niestety daje mi następujące 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.

Odpowiedz

3

spróbować czegoś takiego: Rozszerzenie

znaczników:

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

pojawia się następujący błąd kompilatora: 'Nieznana właściwość„Converter”dla typu„MS.Internal.Markup.MarkupExtensionParser + UnknownMarkupExtension” ' – bitbonk

+0

dobry pomysł, ale to nie działa. Istnieje niedopasowanie: 'ProvideValue' jest wywoływane raz przez parser XAML i nie powinno niczego konwertować. Zamiast tego powinien dostarczyć właściwość dependency coś, co umożliwi konwersję. – jeromerg

+0

Dlaczego nie używałeś podejścia @mkoertgen, biorąc pod uwagę, że on odnawia Twój artykuł? Czy jest jakaś wada? – Dzyann

12

wiem, że jestem bardzo późno do tego, ale co z pewnością działa to przy użyciu BindingProxy dla DynamicResource jak ten

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

następnie zastosowanie konwertera do pełnomocnika

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

To było niesamowite znalezisko! Bonus, za pomocą którego można go również użyć, aby uzyskać dostęp do DataContext zgodnie z opisem w artykule. Już dodane do naszego zestawu narzędzi!:) – MarqueIV

+0

Byłem jednym z ludzi, którzy pierwotnie głosowali na tę odpowiedź, ale właśnie wymyśliłem jeszcze prostsze rozwiązanie, oparte na podobnej koncepcji "proxy", z wyjątkiem tego, że proxy jest obsługiwane automatycznie i przezroczyście za MarkupExtension. Sprawdź mój wpis na ten temat ... http://stackoverflow.com/questions/33816511/heres-how-to-create-a-dynamicresourcebinding-that-supports-converters-stringfo – MarqueIV

+0

Podoba mi się to! Zauważ, że rozszerzenia znaczników mogą być trudne do odkrycia przez XAML, chyba że przeniesiesz je do oddzielnego projektu/zespołu. – mkoertgen

1

Podoba mi się odpowiedź mkoertgena.

Oto przystosowany przykład dla proxy IValueConverter w VB.NET, który działał dla mnie. Mój zasób "VisibilityConverter" jest teraz zawarty jako DynamicResource i przekazywany z użyciem konwertera "VisibilityConverterProxy".

Zastosowanie:

... 
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}}" 

Kod:

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 

nazw Koniec