当嵌入到用户控件中时,在资源上找不到自定义附加 属性
Custom attached property not found on resource when embedded in user control
我有一个资源需要根据使用的地方使用不同的颜色,所以我使用这个附件 属性:
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));
}
我们定义符号并在 window 或用户控件中像这样使用它(这当然简化了很多,资源例如在单独的文件中定义):
<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 包装在上面的代码片段中:
<main:OuterControl>
<ContentControl Content="{StaticResource SomeColorfulSymbol}"/>
</main:OuterControl>
在VS设计器里很好看,一个标题加上一个矩形,就是FillBrush默认的红色。然而在运行时我们只得到标题。矩形没有颜色 (UnsetValue),我们得到这个绑定错误:
System.Windows.Data Error: 40 : BindingExpression path error:
'(main:AssetProperties.FillBrush)' property not found on 'object'
''Rectangle' (Name='')'.
BindingExpression:Path=(main:AssetProperties.FillBrush);
DataItem='Rectangle' (Name=''); target element is 'Rectangle'
(Name=''); target property is 'Fill' (type 'Brush')
如果我在包裹的符号之前添加一个不可见的符号实例,它会再次起作用,即出现一个红色矩形:
<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 相关的行为,我更喜欢这种方法。
为防止出现以下问题,请尝试明确指定路径 属性,例如:{Binding Path=(main:....}
<Rectangle x:Key="SomeColorfulSymbol" x:Shared="False" Width="10" Height="10" Fill="{Binding Path=(main:AssetProperties.FillBrush), RelativeSource={RelativeSource Self}}" />
我有一个资源需要根据使用的地方使用不同的颜色,所以我使用这个附件 属性:
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));
}
我们定义符号并在 window 或用户控件中像这样使用它(这当然简化了很多,资源例如在单独的文件中定义):
<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 包装在上面的代码片段中:
<main:OuterControl>
<ContentControl Content="{StaticResource SomeColorfulSymbol}"/>
</main:OuterControl>
在VS设计器里很好看,一个标题加上一个矩形,就是FillBrush默认的红色。然而在运行时我们只得到标题。矩形没有颜色 (UnsetValue),我们得到这个绑定错误:
System.Windows.Data Error: 40 : BindingExpression path error: '(main:AssetProperties.FillBrush)' property not found on 'object' ''Rectangle' (Name='')'. BindingExpression:Path=(main:AssetProperties.FillBrush); DataItem='Rectangle' (Name=''); target element is 'Rectangle' (Name=''); target property is 'Fill' (type 'Brush')
如果我在包裹的符号之前添加一个不可见的符号实例,它会再次起作用,即出现一个红色矩形:
<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 相关的行为,我更喜欢这种方法。
为防止出现以下问题,请尝试明确指定路径 属性,例如:{Binding Path=(main:....}
<Rectangle x:Key="SomeColorfulSymbol" x:Shared="False" Width="10" Height="10" Fill="{Binding Path=(main:AssetProperties.FillBrush), RelativeSource={RelativeSource Self}}" />