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

本文关键字:对象 按钮 为什么 | 更新日期: 2023-09-27 18:11:42

我正在探索windows phone运行时应用程序模板。但是我看到了一个奇怪的事情。

我有按钮定义在Xaml与ContentTemplate设置在它。我想提取这个按钮的ContentTemplate中定义的Image控件。但是它是空的

Xaml code:-

<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>

按钮点击事件:-

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
}

有人能查一下为什么会这样吗?

编辑:-我已经打破了我的问题,达到了这个非常底部的简单水平,看到这个之后,我只是不明白为什么会发生这种情况?

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

这是奇怪的行为。它应该有堆栈面板和图像在控制模板。作为一种工作,你可以使用ContentTemplateRoot来获取图像和stackpanel。我已经测试过了,它正在工作。

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

希望有帮助

编辑:

有关FindName不工作的详细信息,请参见on MSDN的备注部分. 以下是一些相关的引用

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

由于您正在使用DataTemplate,所以xaml对象树不是连续的,所以这就是为什么FindName无法从xaml树中找到控件的原因。