【问题标题】:TemplatedParent Binding in Resources of ControlTemplateControlTemplate 资源中的 TemplatedParent 绑定
【发布时间】:2014-08-26 09:50:28
【问题描述】:

这是我的场景:我有一个相当大的自定义控件的控件模板。为了封装该自定义控件的其中一项功能的代码,我想引入一个辅助类(称为 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 绑定在资源部分不起作用?

感谢您的所有提示!

【问题讨论】:

    标签: wpf


    【解决方案1】:

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

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

    您必须将类实现更改为:

    public sealed class Internals : Freezable
    

    格鲁瑟,

    彼得 ;)

    【讨论】:

      【解决方案2】:

      当您将Internals 创建为资源时,它不是VisualTree 的一部分,因此不会对其应用绑定

      一旦在Grid 中定义它,它就会成为VisualTree 的一部分。

      【讨论】:

      • 你是对的,Internals 对象不是 VisualTree 的一部分。我对它不是LogicalTree的一部分吗?我的测试在 VisualTree 和 LogicalTree 中都没有找到该对象。我剩下的问题是:资源中是否可以有绑定(例如使用 RelativeSource TemplatedParent)?
      • 另外一个问题:我还没有找到详细解释绑定引擎的网站。你能帮帮我吗?我想了解详情。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-10
      • 2012-10-28
      • 1970-01-01
      • 2017-10-29
      相关资源
      最近更新 更多