Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
856 views
in Technique[技术] by (71.8m points)

c# - Converter with Dependency Properties

I have problems implementing a custom DependencyObject:

I need a converter which sets or unsets a enum flag in a bound property. Therefore I created a IValueConverter derieved from FrameworkElement with two DependencyProperties: Flag (the flag which is set/unset by the converter) and Flags (the value/property to modify). The parent UserControl (Name = EnumerationEditor) provides the property to which the converter is bound.

A ListBox generates CheckBoxes and the converter instances which are used to modify the property via a DataTemplate. Each CheckBox/converter instance is used for one flag. I use the following XAML code:

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

The strange thing: The Label works fine - but the converter does not. I get the error:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=EnumerationEditor'. BindingExpression:Path=Value; DataItem=null; target element is 'EnumerationConverter' (Name=''); target property is 'Flags' (type 'Enum')

I don't understand why, the binding is basically the same...

Here is the code for the converter:

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

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A converter is not a FrameworkElement so it should not inherit from that class, at best use DependencyObject.

Since the converter is not in any tree that binding will not work, you can try:

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

(However this should be placed in the Resources of the UserControl and referenced, otherwise the x:Reference will cause a cyclical dependency error.)

Note that the Flag binding tries to bind to the DataContext which might not work as the DataContext may not be inherited for the same reasons that ElementName and RelativeSource will not work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...