ControlTemplate资源中的TemplatedParent绑定

时间:2014-08-26 09:50:28

标签: wpf

这是我的场景:我有一个自定义控件的控件模板,它相当大。为了封装该自定义控件的某个功能的代码,我想介绍一个帮助器类(称为Internals)。该类具有逻辑代码并提供一些属性,这些属性应该在ControlTemplate中的Bindings中使用。

因此,我需要在XAML中创建此类的实例,并将TemplatedParent绑定到Internals类的依赖项属性。我现在的问题是对应用ControlTemplate的对象的具体绑定。我创造了一个小概念证明:

MainWindow.xaml:

<Window x:Class="WpfProofOfConcept.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpfProofOfConcept="clr-namespace:WpfProofOfConcept"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow" 
    Height="650" 
    Width="525">
<Window.Resources>
    <Style TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Grid.Resources>
                            <wpfProofOfConcept:Internals x:Key="InternalsKey"
                                                         Base="{Binding Path=., RelativeSource={RelativeSource TemplatedParent}}" />
                        </Grid.Resources>

                        <Grid.RenderTransform>
                            <RotateTransform Angle="20" />
                        </Grid.RenderTransform>

                        <!-- if uncommented, Binding to Base is working -->
                        <!--<wpfProofOfConcept:Internals Base="{Binding Path=., RelativeSource={RelativeSource TemplatedParent}}" />-->

                        <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter> 
    </Style>
</Window.Resources>
<Grid>
    <Button>
        <TextBlock>Some text</TextBlock>
    </Button>
</Grid>
</Window>

Internals.cs:

public sealed class Internals : FrameworkElement
{
    public static readonly DependencyProperty BaseProperty =
        DependencyProperty.Register("Base", typeof(object), typeof(Internals), new PropertyMetadata((o, s) => { }));

    public object Base
    {
        get { return (object)GetValue(BaseProperty); }
        set { SetValue(BaseProperty, value); }
    }

    public Internals()
    {
    }
}

我需要在我的Internals对象中引用模板应用的具体对象 - 因此是TemplatedParent绑定。它不起作用,我没有在输出中得到任何绑定错误。

奇怪的是,当在资源部分之外创建Internals对象时它会起作用(请参阅XAML代码中的注释行)。我不

还有一件事让我困惑:在Silverlight中,绑定到资源部分中的TemplatedParent是有效的。这似乎是一个WPF问题。

您对如何完成此绑定有任何想法吗?或者你能解释为什么TemplatedParent绑定在资源部分不起作用吗?

感谢你的所有提示!

2 个答案:

答案 0 :(得分:0)

当您创建Internals作为资源时,它不是VisualTree的一部分,因此绑定未应用于它

Grid内定义后,它就会成为VisualTree的一部分。

答案 1 :(得分:0)

可以从资源中创建绑定!但是资源中的对象必须是可冻结的对象,例如它的类必须扩展Freezable。有关更多信息,请查看WPF博士http://drwpf.com/blog/2008/05/22/leveraging-freezables-to-provide-an-inheritance-context-for-bindings/的这个链接:

  

除了上面的场景(freezable被设置为   依赖项对象上的依赖属性值),这是增强的   允许继承树和继承上下文的概念   对画笔,动画和其他可冻结对象的绑定有效   当这些对象放在资源字典中时。

您必须将类实现更改为:

public sealed class Internals : Freezable

Grüße,

彼得;)