访问ControlTemplate中的控件

toy*_*fun 21 c# wpf controltemplate c#-4.0

这是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>
Run Code Online (Sandbox Code Playgroud)

我想要访问名为的TextBlock textBlock2.
我试图覆盖OnApplyTemplate但是得到了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");
Run Code Online (Sandbox Code Playgroud)

gridInTemplate为null(从MSDN获取的样本).
当然,ct#都是null.

我在这里错过了什么?

dev*_*hog 20

如果您已重写OnApplyTemplate,则不要使用FindResource()或Template.FindName()或任何使用VisualTreeHelper的黑客攻击.只是用this.GetTemplateChild("textBlock2");

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

检查此链接:

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

如果您的示例是microsoft示例,那么我建议您再次阅读.你可能已经跳过了一些东西.

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

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


Tho*_*que 6

您的代码是正确的,但可能不在正确的位置...... FindName只有在应用模板后才能使用.通常,OnApplyTemplate在自定义控件中覆盖时使用它.由于您没有创建自定义控件,因此可以在按钮的Loaded事件中执行此操作.


Ram*_*esh 5

请尝试以下代码.这将返回模板化元素.

this.GetTemplateChild("ControlName");
Run Code Online (Sandbox Code Playgroud)


小智 1

如果您可以获得网格控制,请尝试使用以下代码

TextBlock textBlock2 = (TextBlock)gridInTemplate.Children[1];
Run Code Online (Sandbox Code Playgroud)