Как я могу установить свойство зависимости для статического ресурса?

Я пытаюсь обойти тот факт, что не могу указать динамическое значение для ConverterParameter. см. мой другой вопрос, почему мне нужно привязать динамическое значение к ConverterParameter - Мне не нравятся опубликованные в настоящее время решения, потому что все они требуют ненужных изменений в моей модели представления.

Чтобы попытаться решить эту проблему, я создал собственный преобразователь и выставил свойство зависимости для этого преобразователя:

public class InstanceToBooleanConverter : DependencyObject, IValueConverter
{
    public object Value
    {
        get { return (object)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(object), typeof(InstanceToBooleanConverter), null);

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value != null && value.Equals(Value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? Value : Binding.DoNothing;
    }
}

Есть ли способ установить это значение с помощью привязки (или установщика стиля или другого сумасшедшего метода) в моем XAML?

<ItemsControl ItemsSource="{Binding Properties}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type local:SomeClass}">
            <DataTemplate.Resources>
                <!-- I'd like to set Value to the item from ItemsSource -->
                <local:InstanceToBooleanConverter x:Key="converter" Value="{Binding Path=???}" />
            </DataTemplate.Resources>
<!- ... ->

Примеры, которые я видел до сих пор, привязываются только к статическим ресурсам.

Изменить:

Я получил отзыв о том, что существует только один экземпляр преобразователя с опубликованным мной XAML.

Я могу обойти это, передав ресурс под свой контроль:

<ItemsControl ItemsSource="{Binding Properties}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type local:SomeClass}">
            <RadioButton Content="{Binding Name}" GroupName="Properties">
                <RadioButton.Resources>
                    <!-- I'd like to set Value to the item from ItemsSource -->
                    <local:InstanceToBooleanConverter x:Key="converter"
                                                      Value="{Binding Path=???}" />
                </RadioButton.Resources>
                <RadioButton.IsChecked>
                    <Binding Path="DataContext.SelectedItem"
                             RelativeSource="{RelativeSource AncestorType={x:Type Window}}"
                             Converter="{StaticResource converter}" />
                </RadioButton.IsChecked>
            </RadioButton>
<!- ... ->

Таким образом, эта проблема не блокируется необходимостью совместного использования экземпляра конвертера :)


person Merlyn Morgan-Graham    schedule 05.05.2011    source источник


Ответы (2)


К сожалению, это не сработает - я уже шел по этому пути раньше, и оказалось, что все элементы в ItemsControl используют один и тот же преобразователь. Я думаю, это связано с тем, как работает анализатор XAML.

person default.kramer    schedule 05.05.2011
comment
Да, я видел, что это проблема. Однако я заметил, что если я устанавливаю ресурс в элементе управления, то получаю экземпляр для каждого элемента управления. Я могу изменить свой вопрос, чтобы сделать это, если это имеет больше смысла. - person Merlyn Morgan-Graham; 06.05.2011

Во-первых, вы можете указать преобразователь в словаре ресурсов более высокого уровня и установить x:Shared на false, во-вторых, если вы хотите "установить значение для элемента из ItemsSource", как вы аннотировали, вы можете просто указать пустую привязку (Value="{Binding}").

person H.B.    schedule 05.05.2011
comment
Спасибо за x:Shared информацию. Что касается привязки, кажется, что установщик для моего свойства зависимостей никогда не вызывается, когда я делаю Value="{Binding}". - person Merlyn Morgan-Graham; 06.05.2011
comment
Установщики свойств зависимостей не используются внутренними механизмами, они предназначены только для доступа кода программной части. Поэтому в них никогда нельзя помещать какой-либо код, кроме вызовов SetValue/GetValue. - person H.B.; 06.05.2011
comment
Вы правы в том, что сеттер не вызывается. Если я перехожу с Value="{Binding}" на Value="{StaticResource someOtherResource}, геттер возвращает этот экземпляр статического ресурса, но сеттер никогда не вызывается. Но когда я возвращаюсь к Value="{Binding}", геттер возвращает null. - person Merlyn Morgan-Graham; 06.05.2011
comment
Неважно, привязка в конце концов не является значением. (В некоторых точках привязки может не возвращаться значение, поэтому GetValue возвращает null) - person H.B.; 06.05.2011
comment
(В некоторых точках привязки может не возвращаться значение, поэтому GetValue возвращает null). Вы имеете в виду в некоторые моменты во время запуска приложения/создания пользовательского интерфейса или в некоторые моменты во время работы приложения? При тестировании я использовал DataContext (установленный в конструкторе), который гарантировал, что ничего не будет нулевым. Я начинаю думать, что эта привязка происходит во время компиляции, а затем сериализуется. - person Merlyn Morgan-Graham; 06.05.2011
comment
Извините, что не ответил, может я как-то проглядел ваш комментарий. Связывание действительно происходит во время выполнения, но мой анализ, вероятно, был просто неверным, я бы сказал, что это связывание не будет работать, потому что ValueConverters не имеет DataContext или даже соединения с визуальным деревом. Ваши источники ограничены свойством Source, я ожидаю, что DataContext (без явного источника), ElementName и RelativeSource здесь не будут работать. - person H.B.; 02.01.2012