ControlTemplate中的DataBinding与DependencyProperty一起工作,但仍会引发错误

时间:2016-08-09 07:42:18

标签: c# wpf data-binding dependency-properties

我有一个带有Angle DependencyProperty的自定义按钮:

public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
        "Angle",
        typeof(float),
        typeof(TriangularButton),
        new FrameworkPropertyMetadata(0f, FrameworkPropertyMetadataOptions.AffectsRender));

public float Angle
{
    get { return (float)GetValue(AngleProperty); }
    set { SetValue(AngleProperty, value); }
}

在ControlTemplate中我想绑定到Angle。我尝试了几种方法(见下文),每种方法都有效,但是我得到了一个System.Windows.Data错误。我该如何摆脱它?

我尝试了什么:

<Button.Template>
    <ControlTemplate TargetType="Button">
        <Path ...>
            <Path.RenderTransform>
                <RotateTransform Angle="{Binding Angle, RelativeSource={RelativeSource TemplatedParent}}"/>
            </Path.RenderTransform>
        </Path>
    </ControlTemplate>
</Button.Template>

然后我得到:

  

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径=角度;的DataItem = NULL; target元素是'RotateTransform'(HashCode = 55197304); target属性为'Angle'(类型'Double')

当我这样做时:

<Button.Template>
    <ControlTemplate TargetType="Button">
        <Path ...>
            <Path.RenderTransform>
                <RotateTransform Angle="{Binding Angle, RelativeSource={RelativeSource AncestorType=Button}}"/>
            </Path.RenderTransform>
        </Path>
    </ControlTemplate>
</Button.Template>

然后我得到:

  

System.Windows.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.Button',AncestorLevel ='1''。 BindingExpression:路径=角度;的DataItem = NULL; target元素是'RotateTransform'(HashCode = 24935945); target属性为'Angle'(类型'Double')

修改

感谢this answer我发现原因可能是因为Button最初不可见。如果我将Button放在最初可见的位置,则错误就会消失。当我在最初不可见的某个地方使用Button时,有没有办法摆脱错误?

1 个答案:

答案 0 :(得分:0)

如果在按钮

上指定DataContext,则无需指定源

编辑:

XAML:

<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Test"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TabControl>
        <TabItem Header="1"/>
        <TabItem Header="2">
            <Grid>
                <local:TriangularButton Angle="45" Width="100" Height="100">
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <Path Stroke="Red" RenderTransformOrigin="0.5,0.5">
                                <Path.Data>
                                    <RectangleGeometry Rect="0,0,100,100"/>
                                </Path.Data>
                                <Path.RenderTransform >
                                    <RotateTransform Angle="{Binding Angle, RelativeSource={RelativeSource TemplatedParent}}"/>
                                </Path.RenderTransform>
                            </Path>
                        </ControlTemplate>
                    </Button.Template>
                </local:TriangularButton>
            </Grid>
        </TabItem>
    </TabControl>

</Grid>

DP

rusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows;
using System.Windows.Controls;

namespace Test
{
    public class TriangularButton : Button
    {
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
        "Angle",
        typeof(float),
        typeof(TriangularButton),
        new FrameworkPropertyMetadata(0f, FrameworkPropertyMetadataOptions.AffectsRender));

    public float Angle
    {
        get { return (float)GetValue(AngleProperty); }
        set { SetValue(AngleProperty, value); }
    }
}

}  代码在这里

即使我从另一个标签打开,它也很有效。

First tab opened

Tab with button

您可以在路径中添加RenderTransformOrigin。