我正在探索 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
}
任何人都可以查看这是为什么会发生这种情况吗?
编辑: - 我已经解决了我的问题并达到了这个非常简单的水平,看到这个后我才知道为什么会发生这种情况?
答案 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树中找到控件的原因。
希望这能解释......