XAML 具有相关性属性的值转换器

kpbwa7wx  于 2023-06-19  发布在  其他
关注(0)|答案(2)|浏览(174)

我在实现自定义DependencyObject时遇到问题:
我需要一个转换器,设置或取消设置一个枚举标志在一个绑定属性。因此,我创建了一个从FrameworkElement派生的IValueConverter,其中包含两个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>
    • 奇怪的事情:标签工作正常-但转换器不能。**我得到错误:

系统. Windows.数据错误:4:找不到具有引用“ElementName = EnumerationEditor”的绑定的源。String:String = String; String = null;目标元素为“EnumerationConverter”(Name ='');目标属性为“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

}
vxf3dgd4

vxf3dgd41#

转换器不是FrameworkElement,所以它不应该从该类继承,最好使用DependencyObject
由于转换器不在任何绑定将无法工作的树中,您可以尝试:

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

(但是,这应该放在UserControlResources中并引用,否则x:Reference将导致循环依赖性错误。
请注意,Flag绑定试图绑定到DataContext,这可能不起作用,因为DataContext可能不会被继承,原因与ElementNameRelativeSource不起作用相同。

carvr3hs

carvr3hs2#

结论

我决定使用两个UserControl来解决这个问题; FlagControl和EnumerationEditorControl。
FlagControl有两个依赖项属性

  • 标志(系统枚举):确定控件设置/清除哪个标志
  • 值(系统枚举):绑定到设置/清除标志的属性/值。

EnumerationEditorControl有一个依赖项属性:

  • 值(系统枚举):设置标志的属性/值。

EnumerationEditorControl使用DataTemplate示例化FlagControls。DataTemplate将FlagControl.Flag属性绑定到DataContext,将FlagControl.Value属性绑定到EnumerationEditorControl.Value属性。
这样我就不需要一个转换器和逻辑是明确分开的。
感谢您的建议、评论和回复!

相关问题