我正在创建一个自定义UserControl,它将充当容器,在其内容后面显示一个自定义水印。
ControlTemplate的相关部分(我将在下面给出完整的内容)是
<TextBlock
Text="{TemplateBinding WatermarkText}"
Foreground="{TemplateBinding WatermarkBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="Bold">
<TextBlock.LayoutTransform>
<RotateTransform Angle="{Binding WatermarkAngle,RelativeSource={RelativeSource AncestorType={x:Type local:WatermarkUserControl}}}"/>
</TextBlock.LayoutTransform>
</TextBlock>
我的UserControl具有WatermarkText,WatermarkBrush,WatermarkAngle和WatermarkVisibility的依赖属性(我将在下面包含)。请注意,WatermarkText,WatermarkBrush和WatermarkVisibility的TemplateBinding都可以正常工作。
使用TemplateBinding for WatermarkAngle不起作用,因为TemplateBinding是一个轻量级的#34;绑定&#34;,所以它不支持inheritance context。我最终得到的WatermarkAngle绑定(上图)实际上有效;然而,报告了一个绑定错误:
System.Windows.Data错误:4:找不到绑定源 参考&#39; RelativeSource FindAncestor, AncestorType =&#39; [编辑名称空间] .WatermarkUserControl&#39;,AncestorLevel =&#39; 1&#39;&#39;。 BindingExpression:路径= WatermarkAngle;的DataItem = NULL;目标要素 是&#39; RotateTransform&#39; (的HashCode = 59772470);目标属性是&#39;角度&#39; (键入&#39; Double&#39;)
那么有没有办法更好地做到这一点,这可以避免报告错误?为什么它会报告绑定错误,因为绑定实际上有效? (如果我更改了值,则会反映出来。)
结束这个问题。以下是您需要的所有部分,以满足MCVE:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
public class WatermarkUserControl : UserControl
{
public static readonly DependencyProperty WatermarkTextProperty =
DependencyProperty.Register(nameof(WatermarkText), typeof(string), typeof(WatermarkUserControl), new PropertyMetadata("Watermark"));
public static readonly DependencyProperty WatermarkBrushProperty =
DependencyProperty.Register(nameof(WatermarkBrush), typeof(Brush), typeof(WatermarkUserControl), new PropertyMetadata(new SolidColorBrush(Colors.LightGray)));
public static readonly DependencyProperty WatermarkAngleProperty =
DependencyProperty.Register(nameof(WatermarkAngle), typeof(double), typeof(WatermarkUserControl), new PropertyMetadata(0d));
public static readonly DependencyProperty WatermarkVisibilityProperty =
DependencyProperty.Register(nameof(WatermarkVisibility), typeof(Visibility), typeof(WatermarkUserControl), new PropertyMetadata(Visibility.Visible));
public string WatermarkText
{
get { return (string)GetValue(WatermarkTextProperty); }
set { SetValue(WatermarkTextProperty, value); }
}
public Brush WatermarkBrush
{
get { return (Brush)GetValue(WatermarkBrushProperty); }
set { SetValue(WatermarkBrushProperty, value); }
}
public double WatermarkAngle
{
get { return (double)GetValue(WatermarkAngleProperty); }
set { SetValue(WatermarkAngleProperty, value); }
}
public Visibility WatermarkVisibility
{
get { return (Visibility)GetValue(WatermarkVisibilityProperty); }
set { SetValue(WatermarkVisibilityProperty, value); }
}
}
的ResourceDictionary:
<Style x:Key="WatermarkUserControlBaseStyle" TargetType="local:WatermarkUserControl">
<Setter Property="Padding" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WatermarkUserControl">
<Grid>
<local:NoSizeDecorator Visibility="{TemplateBinding WatermarkVisibility}">
<Viewbox>
<TextBlock
Text="{TemplateBinding WatermarkText}"
Foreground="{TemplateBinding WatermarkBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="Bold">
<TextBlock.LayoutTransform>
<RotateTransform Angle="{Binding WatermarkAngle,RelativeSource={RelativeSource AncestorType={x:Type local:WatermarkUserControl}}}"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Viewbox>
</local:NoSizeDecorator>
<ContentPresenter Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DraftWatermarkStyle" TargetType="local:WatermarkUserControl" BasedOn="{StaticResource WatermarkUserControlBaseStyle}">
<Setter Property="WatermarkText" Value="DRAFT"/>
<Setter Property="WatermarkBrush" Value="LightPink"/>
<Setter Property="WatermarkAngle" Value="-20"/>
</Style>
NoSizeDecorator定义为here。
使用示例:
<local:WatermarkUserControl
Style="{StaticResource DraftWatermarkStyle}"
WatermarkVisibility="True">
<StackPanel>
<Label Content="Mr Smith"/>
<Label Content="1 High Street"/>
<Label Content="London"/>
</StackPanel>
</local:WatermarkUserControl>
答案 0 :(得分:0)
我已经找到了一种方法。它使错误消失了,它似乎仍然有用,我还没有发现任何副作用。
我将RotateTransform声明为ControlTemplate中Viewbox内的本地资源,然后将其作为StaticResource绑定到TextBlock的LayoutTransform属性。所以问题的新版Viewbox看起来像这样:
<Viewbox>
<Viewbox.Resources>
<RotateTransform x:Key="RotateWatermarkTransform" Angle="{Binding WatermarkAngle,RelativeSource={RelativeSource TemplatedParent}}"/>
</Viewbox.Resources>
<TextBlock
Text="{TemplateBinding WatermarkText}"
Foreground="{TemplateBinding WatermarkBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="Bold"
LayoutTransform="{StaticResource RotateWatermarkTransform}"/>
</Viewbox>