具有依赖属性的转换器

时间:2011-07-28 08:49:57

标签: c# wpf xaml data-binding converter

我在实现自定义DependencyObject时遇到问题:

我需要一个转换器来设置或取消绑定属性中的枚举标志。因此,我创建了一个IValueConverter,它来自FrameworkElement,带有两个DependencyProperties:Flag(由转换器设置/取消设置的标志)和Flags(要修改的值/属性)。父UserControl(Name = EnumerationEditor)提供转换器绑定的属性。

ListBox生成CheckBoxes和转换器实例,用于通过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:路径=值;的DataItem = NULL; target元素是'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 个答案:

答案 0 :(得分:5)

转换器不是FrameworkElement,因此它不应该继承该类,最好使用DependencyObject

由于转换器不在任何树中,绑定不起作用,您可以尝试:

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

(但是这应该放在Resources的{​​{1}}中并引用,否则x:Reference会导致周期性依赖性错误。)

请注意,UserControl绑定尝试绑定到Flag,这可能无法正常运行,因为DataContext和{DataContext可能无法继承ElementName 1}}将无效。

答案 1 :(得分:0)

<强>结论

我决定使用两个UserControl来解决问题; FlagControl和EnumerationEditorControl。

FlagControl有两个依赖属性

  • Flag(System.Enum):确定控件设置/清除哪个标志
  • Value(System.Enum):绑定到设置/清除标志的属性/值。

EnumerationEditorControl有一个依赖属性:

  • Value(System.Enum):设置标志的propery / value。

EnumerationEditorControl使用DataTemplate实例化FlagControls。 DataTemplate将FlagControl.Flag属性绑定到DataContext,将FlagControl.Value属性绑定到EnumerationEditorControl.Value属性。

这样我就不需要转换器了,逻辑分开了。

感谢您的建议,意见和回复!