【问题标题】:Custom attached property not found on resource when embedded in user control嵌入用户控件时在资源上找不到自定义附加属性
【发布时间】:2015-09-25 06:25:25
【问题描述】:

我有一个资源需要根据它的使用位置而不同的颜色,所以我使用这个附加属性:

public static class AssetProperties
{
    public static Brush GetFillBrush(DependencyObject obj)
    {
        return (Brush)obj.GetValue(FillBrushProperty);
    }

    public static void SetFillBrush(DependencyObject obj, Brush value)
    {
        obj.SetValue(FillBrushProperty, value);
    }

    public static readonly DependencyProperty FillBrushProperty =
        DependencyProperty.RegisterAttached("FillBrush",
        typeof(Brush),
        typeof(AssetProperties),
        new FrameworkPropertyMetadata(new BrushConverter().ConvertFrom("#FFE41300"), FrameworkPropertyMetadataOptions.Inherits));
}

我们定义符号并在窗口或用户控件中使用它(这当然简化了很多,例如资源在单独的文件中定义):

<Grid>
    <Grid.Resources>
        <ResourceDictionary>                
            <Rectangle x:Key="SomeColorfulSymbol" x:Shared="False" Width="10" Height="10" 
                    Fill="{Binding (main:AssetProperties.FillBrush), RelativeSource={RelativeSource Self}}" />
        </ResourceDictionary>
    </Grid.Resources>

    <ContentControl Content="{StaticResource SomeColorfulSymbol}" main:AssetProperties.FillBrush="Blue"/>     
</Grid>

这按预期工作,出现一个漂亮的蓝色矩形。在不设置附加属性的情况下,矩形是 FillBrush 附加属性的默认红色。

问题是当我们尝试在这样定义的自定义用户控件中使用符号时:

OuterControl.xaml:

<UserControl x:Class="AttachedPropertyResourceTest.OuterControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <StackPanel>
            <TextBlock Text="Some title"/>
            <ContentControl Content="{Binding InnerContent, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
        </StackPanel>
    </Grid>
</UserControl>

OuterControl.xaml.cs:

[ContentProperty("InnerContent")]
public partial class OuterControl
{
    public FrameworkElement InnerContent
    {
        get { return (FrameworkElement)GetValue(InnerContentProperty); }
        set { SetValue(InnerContentProperty, value); }
    }

    public static readonly DependencyProperty InnerContentProperty =
        DependencyProperty.Register("InnerContent", typeof(FrameworkElement), typeof(OuterControl), new FrameworkPropertyMetadata(null));

    public OuterControl()
    {
        InitializeComponent();
    }
}

现在,如果我像这样将 ContentControl 包装在上面的 sn-p 中:

<main:OuterControl>
    <ContentControl Content="{StaticResource SomeColorfulSymbol}"/>
</main:OuterControl>

在 VS 设计器中看起来不错,一个标题加上一个矩形,这是 FillBrush 的默认红色。然而,在运行时我们只得到标题。矩形没有颜色(UnsetValue),我们得到这个绑定错误:

System.Windows.Data 错误:40:BindingExpression 路径错误: 在“对象”上找不到“(主要:AssetProperties.FillBrush)”属性 ''矩形'(名称='')'。 BindingExpression:Path=(main:AssetProperties.FillBrush); DataItem='矩形'(名称='');目标元素是“矩形” (名称='');目标属性是“填充”(输入“画笔”)

如果我在包装之前添加一个不可见的符号实例,它会再次起作用,即出现一个红色矩形:

<ContentControl Content="{StaticResource SomeColorfulSymbol}" Visibility="Collapsed"/>
<main:OuterControl>
    <ContentControl Content="{StaticResource SomeColorfulSymbol}"/>
</main:OuterControl>

一个问题是附加属性没有注册,当我在 RegisterAttached 方法上放置一个断点时,如果没有额外的不可见 ContentControl,它就不会被调用。然而,这只是问题的一部分,例如像这样强制注册不起作用:

<StackPanel>
    <TextBlock Text="I'm red!" Background="{Binding (main:AssetProperties.FillBrush), RelativeSource={RelativeSource Self}}"/>
    <main:OuterControl>
        <ContentControl Content="{StaticResource SomeColorfulSymbol}"/>
    </main:OuterControl>
</StackPanel>

文本“I'm red”实际上是红色的,并且附加的属性已注册,但我们得到完全相同的绑定错误。

我也尝试不使用ContentProperty["InnerContent"],在 xaml 中显式设置 InnerContent 属性,结果相同。

有人能解释一下吗?

也许使用控件模板而不是 OuterControl 不会有这个问题 (?),但是有很多与 OuterControl 相关的行为,我更喜欢这种方法。

【问题讨论】:

  • 问题是当我们尝试在这样的自定义用户控件中使用符号时...像什么?我可能会失明,但我没有看到您使用 FillBrush 附加属性的第二个示例。
  • 我在第二个例子中省略了附加属性的设置,以表明它不是属性继承的问题。我希望获得 FillBrush(红色)的默认值,但会出现绑定错误。抱歉,如果不清楚,我会尝试编辑并使其更清晰。
  • 尝试像 {Binding Path=(main:....} 一样明确指定路径属性,它可能会有所帮助
  • @Alexis 这完全有效,谢谢一百万!如果您想发布答案,我会将其标记为正确。

标签: wpf xaml user-controls resourcedictionary attached-properties


【解决方案1】:

为防止出现以下问题,请尝试明确指定路径属性,例如:{Binding Path=(main:....}

 <Rectangle x:Key="SomeColorfulSymbol" x:Shared="False" Width="10" Height="10" Fill="{Binding Path=(main:AssetProperties.FillBrush), RelativeSource={RelativeSource Self}}" />

【讨论】:

    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2014-01-17
    • 2011-10-05
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多