首页 文章

ControlTemplate LayoutTransform Binding System.Windows.Data错误2或4

提问于
浏览
1

我正在创建一个自定义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没有't work, because TemplateBinding is a lightweight 2612317 , so it doesn' t支持inheritance context . 我最终得到的WatermarkAngle绑定(上图)实际上有效;但是报告了绑定错误:

System.Windows.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='[redacted namespace] .WatermarkUserControl',AncestorLevel ='1'' . BindingExpression:路径= WatermarkAngle;的DataItem = NULL; target元素是'RotateTransform'(HashCode = 59772470); target属性为'Angle'(类型'Double')

那么有没有办法更好地做到这一点,这可以避免报告错误?为什么它会报告绑定错误,因为绑定实际上有效? (如果我更改了值,则会反映出来 . )


结束了这个问题 . 以下是您需要的所有部件,以满足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>

1 回答

  • 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>
    

相关问题