Использовать IValueConverter с DynamicResource? - PullRequest
14 голосов
/ 26 января 2011

Есть ли способ определить конвертер при использовании расширения DynamicResource? Что-то в строках

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

что, к сожалению, дает мне следующие исключения:

«DynamicResourceExtension» не может быть установить в свойстве «Source» типа 'Binding'. DynamicResourceExtension может быть только устанавливается на DependencyProperty DependencyObject.

Ответы [ 4 ]

15 голосов
/ 15 июня 2014

Я знаю, что я действительно опоздал к этому, но определенно работает использование BindingProxy для DynamicResource, как это

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

Затем применение преобразователя к прокси

<RowDefinition Height="{Binding Source={StaticResource someHeightProxy}, Path=Data, Converter={StaticResource gridLengthConverter}}" />
4 голосов
/ 26 января 2011

Попробуйте что-то подобное:

Расширение разметки:

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}}" />
1 голос
/ 20 ноября 2015

@ Пост Томаса очень близок, но, как уже отмечали другие, он выполняется только во время выполнения MarkupExtension.

Вот решение, которое выполняет истинное связывание, не требует объектов «прокси»и записывается так же, как и любая другая привязка, за исключением того, что вместо источника и пути вы даете ему ключ ресурса ...

Как создать привязку DynamicResourceBinding, которая поддерживает конвертеры, StringFormat?

1 голос
/ 25 марта 2015

Мне нравится ответ mkoertgen.

Вот адаптированный пример для прокси IValueConverter в VB.NET, который работал для меня. Мой ресурс «VisibilityConverter» теперь включен как DynamicResource и пересылается с ConverterProxy «VisibilityConverterProxy».

Использование:

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

Код:

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

Конечное пространство имен

...