Подтвердить что ты не робот

Использовать IValueConverter с DynamicResource?

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

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

который, к сожалению, дает мне следующее возбуждение:

A "Динамическое изменение ресурсов" не может быть задано в свойстве "Источник" типа 'Binding'. "DynamicResourceExtension" может быть только установить на DependencyProperty DependencyObject.

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Попробуйте что-то вроде этого:

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

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

Ответ 3

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

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

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

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

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

Ответ 4

Сообщение

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

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

Как вы создаете DynamicResourceBinding, поддерживающее Converters, StringFormat?