为什么按钮的内容模板没有对象?

时间:2014-07-06 13:36:45

标签: c# xaml windows-phone-8 windows-runtime windows-phone-8.1

我正在探索 Windows Phone运行时应用模板。但我看到了一件奇怪的事情。

我在Xaml中定义了Button,其中设置了ContentTemplate。我想提取在这个按钮的ContentTemplate中定义的Image控件。但它无效。

Xaml代码: -

<Button x:Name="PlayButton" Click="PlayButton_OnClick">
        <Button.ContentTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Name="Panel">
                    <Image x:Name="ControlImg" 
                     Width="100"
                    />
                    <TextBlock Text="text block" />
                </StackPanel>
            </DataTemplate>
        </Button.ContentTemplate>

这是按钮Click事件: -

private async void PlayButton_OnClick(object sender, RoutedEventArgs e)
{
        var btn = sender as Button;

        var ct = btn.ContentTemplate; // this part is also not showing controls in it when expending ct at runtime.

        var img = btn.FindName("ControlImg") as Image; // coming null 

        var stckpnl = btn.FindName("Panel") as StackPanel;// coming null
}

任何人都可以查看这是为什么会发生这种情况吗?

编辑: - 我已经解决了我的问题并达到了这个非常简单的水平,看到这个后我才知道为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

这是一种奇怪的行为。它应该在控件模板中堆叠Panel和image。作为解决方法,您可以使用ContentTemplateRoot来获取图像和堆栈面板。我测试了这个,它正在工作。

((StackPanel)btn.ContentTemplateRoot).Children[0] // image

希望这有帮助

修改

有关FindName无法正常工作的详细信息,请参阅 MSDN 上的“备注”部分 。这是一些相关的引用

  

重要为了有效地使用FindName方法,您应该了解XAML名称范围的概念,以及如何在XAML加载时创建XAML名称范围,然后在运行时引用并可能修改。有关更多信息,请参阅XAML名称范围。   Windows运行时代码中FindName的最常见用法将来自生成的XAML页面的InitializeComponent调用。在这种情况下,只有在加载XAML页面后才会调用FindName。 InitializeComponent提供了基础结构,使得通过代码隐藏代码可以方便地访问由XAML加载实例化的任何对象。然后,您可以将对象引用为与标记声明的x:Name共享同一名称的变量。   诸如FindName之类的运行时API正在对应用程序的运行时对象树进行操作,因为它存在于内存中。 当从模板或运行时加载的XAML创建此对象树的一部分时,XAML名称范围通常在该对象树中不连续。结果是在对象树中可能存在给定FindName范围无法找到的命名对象。 在典型应用程序方案中可能遇到的XAML名称范围之间的不连续性是通过应用创建对象的时间模板,或者通过调用XamlReader.Load创建对象,然后将其添加到对象树中。

当您使用DataTemplate时,xaml对象树不是连续的,这就是为什么FindName无法从xaml树中找到控件的原因。

希望这能解释......