【问题标题】:Converter with Dependency Properties具有依赖属性的转换器
【发布时间】:2011-10-14 22:34:05
【问题描述】:

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

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

ListBox 生成 CheckBox 和转换器实例,用于通过 DataTemplate 修改属性。每个 CheckBox/converter 实例用于一个标志。我使用以下 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”的绑定源。绑定表达式:路径=值;数据项=空;目标元素是'EnumerationConverter'(名称='');目标属性是“标志”(类型“枚举”)

不明白为什么,绑定基本一样……

这是转换器的代码:

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

}

【问题讨论】:

  • 是您的用户控件的 EnumerationEditor 部分,您只发布了列表框
  • @anivas:是的,它是 UserControl 本身。它有一个名为 Enum 类型的 Value 的依赖属性。但正如您在 sn-ps 中看到的那样,我对 Label.ToolTip 使用与 Converter 完全相同的绑定。 Label.ToolTip 有效 - 它显示正确的值。但是转换器会产生错误。
  • 转换器不会成为可视化树的一部分,这就是它找不到它的原因。你想做什么?
  • @anivas:我正在尝试为枚举类型的属性(带有标志属性)创建一个编辑器。用户应该能够使用复选框选择标志。转换器应设置/清除属性中的特定标志并确定是否设置了标志。
  • 你最好使用多值转换器,这样你就可以发送你想要的任何绑定。

标签: c# wpf xaml data-binding converter


【解决方案1】:

转换器不是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 不起作用的原因相同。

【讨论】:

  • 你完全正确 - Flag 绑定不起作用。但我可以对这两个项目使用 x:Reference 解决方案,现在它可以工作了。但是我收到很多 System.Windows.Data 错误(6/23)。需要追查错误,但您指出了正确的方向,谢谢!
【解决方案2】:

结论

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

FlagControl 有两个依赖属性

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

EnumerationEditorControl 有一个依赖属性:

  • Value(System.Enum):设置标志的属性/值。

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

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

感谢您的建议、cmets 和回复!

【讨论】:

    猜你喜欢
    • 2016-01-10
    • 2011-04-21
    • 2021-12-04
    • 2016-05-09
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    相关资源
    最近更新 更多