Конвертер со свойствами зависимости - PullRequest
1 голос
/ 28 июля 2011

У меня проблемы с реализацией пользовательского объекта DependencyObject:

Мне нужен конвертер, который устанавливает или отменяет флаг перечисления в связанном свойстве. Поэтому я создал IValueConverter, извлеченный из FrameworkElement с двумя DependencyProperties: Flag (флаг, который устанавливается / отменяется конвертером) и Flags (значение / свойство, которое нужно изменить). Родительский UserControl (Name = EnumerationEditor) предоставляет свойство, к которому привязан конвертер.

ListBox генерирует CheckBox и экземпляры конвертера, которые используются для изменения свойства с помощью DataTemplate. Каждый экземпляр CheckBox / конвертер используется для одного флага. Я использую следующий код XAML:

<ListBox Name="Values" SelectionMode="Extended" BorderThickness="1" BorderBrush="Black" Padding="5">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type system:Enum}">

            <DataTemplate.Resources>
                <Label x:Key="myTestResource" x:Shared="False"
                            Content="{Binding}"
                            ToolTip="{Binding Path=Value, ElementName=EnumerationEditor}"
                            Foreground="{Binding Path=Background, ElementName=EnumerationEditor}"
                            Background="{Binding Path=Foreground, ElementName=EnumerationEditor}"/>
                <converters:EnumerationConverter x:Key="EnumerationConverter" x:Shared="False"
                                                    Flag="{Binding}"
                                                    Flags="{Binding Path=Value, ElementName=EnumerationEditor}"/>
            </DataTemplate.Resources>

            <StackPanel Orientation="Horizontal">
                <CheckBox Content="{Binding}" IsChecked="{Binding Path=Value, ElementName=EnumerationEditor, Converter={StaticResource EnumerationConverter}}"/>
                <ContentPresenter Content="{StaticResource myTestResource}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Странная вещь: Метка работает нормально - но конвертер - нет. Я получаю ошибку:

System.Windows.Data Ошибка: 4: не удается найти источник для привязки со ссылкой «ElementName = EnumerationEditor». BindingExpression: Path = Value; DataItem = NULL; Целевым элементом является EnumerationConverter (Name = ''); Свойство target - Flags (тип Enum)

Я не понимаю, почему привязка в основном такая же ...

Вот код для конвертера:

public class EnumerationConverter : FrameworkElement, IValueConverter
{

    #region IValueConverter

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Parity.Space;
    }

    #endregion

    #region public Enum Flag { get; set; }

    public Enum Flag
    {
        get { return (Enum)this.GetValue(EnumerationConverter.FlagProperty); }
        set { this.SetValue(EnumerationConverter.FlagProperty, value); }
    }

    /// <summary>
    /// Dependency property for Flag.
    /// </summary>
    public static readonly DependencyProperty FlagProperty = DependencyProperty.Register("Flag", typeof(Enum), typeof(EnumerationConverter));

    #endregion

    #region public Enum Flags { get; set; }

    public Enum Flags
    {
        get { return (Enum)this.GetValue(EnumerationConverter.FlagsProperty); }
        set { this.SetValue(EnumerationConverter.FlagsProperty, value); }
    }

    /// <summary>
    /// Dependency property for Flags.
    /// </summary>
    public static readonly DependencyProperty FlagsProperty = DependencyProperty.Register("Flags", typeof(Enum), typeof(EnumerationConverter));

    #endregion

}

Ответы [ 2 ]

5 голосов
/ 28 июля 2011

Преобразователь не является FrameworkElement, поэтому он не должен наследоваться от этого класса, в лучшем случае используйте DependencyObject.

Поскольку конвертер не находится ни в одном дереве, привязка не будет работать, вы можете попробовать:

<converters:EnumerationConverter x:Key="EnumerationConverter" x:Shared="False"
                                 Flag="{Binding}"
                                 Flags="{Binding Path=Value, Source={x:Reference EnumerationEditor}}"/>

(Однако это следует поместить в Resources из UserControl и ссылаться на него, в противном случае x:Reference вызовет ошибку циклической зависимости.)

Обратите внимание, что привязка Flag пытается выполнить привязку к DataContext, который может не работать, поскольку DataContext может не наследоваться по тем же причинам, по которым ElementName и RelativeSource не будут работать.

0 голосов
/ 29 июля 2011

Заключение

Я решил решить эту проблему с помощью двух пользовательских элементов управления; FlagControl и EnumerationEditorControl.

FlagControl имеет два свойства зависимости

  • Флаг (System.Enum): определяет, какой флаг установлен / сброшен элементом управления
  • Значение (System.Enum): привязывается к свойству / значению, в котором установлен / очищен флаг.

EnumerationEditorControl имеет одно свойство зависимости:

  • Значение (System.Enum): свойство / значение, в котором установлены флаги.

EnumerationEditorControl использует DataTemplate для создания экземпляров FlagControls. DataTemplate связывает свойство FlagControl.Flag со свойством DataContext, а свойство FlagControl.Value со свойством EnumerationEditorControl.Value.

Таким образом, мне не нужен конвертер, и логика четко отделена.

Спасибо за предложения, комментарии и ответы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...