访问ControlTemplate中的控件 [英] Accessing a control inside a ControlTemplate

查看:664
本文介绍了访问ControlTemplate中的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是xaml:

<Page.Resources>
    <ControlTemplate x:Key="WeddingButtonBigTemplate" TargetType="Button">
        <Grid>
            <Image x:Name="imgNormal" Source="../Images/Married_button2.png"/>
            <TextBlock x:Name="textBlock2" Style="{StaticResource RegularBlueSpecialBoldText}" LineHeight="28" LineStackingStrategy="BlockLineHeight" HorizontalAlignment="Center" Margin="10,30,10,70" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Stretch" >
                <Run FontSize="20" Text="The event of"></Run>
                <Run FontSize="28" Text="{DynamicResource strBride}"></Run>
            </TextBlock>
        </Grid>
    </ControlTemplate>
</Page.Resources>

<Grid HorizontalAlignment="Center" VerticalAlignment="Top" Width="1000">
    <Button x:Name="btnWedding" HorizontalAlignment="Left" Margin="10,20,0,-49" VerticalAlignment="Top" Template="{StaticResource WeddingButtonBigTemplate}" Foreground="#FF2B4072" Width="380" Click="btnClick" />
</Grid>

我试图访问名为 textBlock2的TextBlock

我已尝试覆盖 OnApplyTemplate 但已获得null。

I'm tring to get access to the TextBlock named textBlock2.
I've tried to override OnApplyTemplate but got null.

我尝试过:

Grid gridInTemplate = (Grid)btnWedding.Template.FindName("grid", btnWedding);
var ct0 = btnWedding.Template.FindName("textBlock2", btnWedding);
var ct1 = btnWedding.FindName("textBlock2");
var ct2 = btnWedding.FindResource("textBlock2");

gridInTemplate为null(取自MSDN的示例)。

ct#

The gridInTemplate is null (sample taken from MSDN).
The ct# are all null, of course.

推荐答案

如果您已经覆盖OnApplyTemplate,那么不要使用FindResource()或Template.FindName()或任何与VisualTreeHelper的黑客。只需使用 this.GetTemplateChild(textBlock2);

If you have overriden OnApplyTemplate then do not use FindResource() or Template.FindName() or any hacks with VisualTreeHelper. Just use this.GetTemplateChild("textBlock2");

WPF中的模板具有自包含的名称。这是因为模板被重新使用,并且当控件的多个实例每个实例化其模板时,模板中定义的任何名称都不能保持唯一。调用GetTemplateChild方法以在实例化之后返回对来自模板的对象的引用。您不能使用FrameworkElement.FindName方法从模板中查找项目,因为FrameworkElement.FindName在更一般的作用域中,并且ControlTemplate类本身和应用后的实例化模板之间没有连接。

Templates in WPF have a self-contained namescope. This is because templates are re-used, and any name defined in a template cannot remain unique when multiple instances of a control each instantiate its template. Call the GetTemplateChild method to return references to objects that come from the template after it is instantiated. You cannot use the FrameworkElement.FindName method to find items from templates because FrameworkElement.FindName acts in a more general scope, and there is no connection between the ControlTemplate class itself and the instantiated template once it is applied.

请检查此链接:

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.gettemplatechild.aspx

如果你的例子是microsoft示例,那么我建议你再读一遍。您可能跳过了某些内容。

If your example is microsoft example then I suggest you to read it again. You might have skipped something.

http:/ /msdn.microsoft.com/en-us/library/bb613586.aspx

总结 - 使用GetTemplateChild()创作自定义控件OnApplyTemplate,并在其他情况下使用Template.FindName。

To sum up - Use GetTemplateChild() when authoring custom control e.g. OnApplyTemplate, and use Template.FindName in other situations.

这篇关于访问ControlTemplate中的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆