Windows Phone 8.1 在 DataTemplate 中切换 TextBlock 的可见性 [英] Windows Phone 8.1 Toggling the visibility of a TextBlock in a DataTemplate
问题描述
我正在构建一个 Windows Phone 8.1 集线器应用程序.其中一个集线器部分包含一个显示文章列表的 ListView.我想向这个集线器部分添加一个文本块,当文章下载失败时,它会显示一条消息.XAML 代码如下:
I'm building a Windows Phone 8.1 Hub Application. One of the hub section contains a ListView that displays a list of articles. I'd like to add a Textblock to this hubsection which displays a message when the articles failed to download. The XAML Code is below:
<HubSection
x:Uid="ArticlesSection"
Header="ARTICLES"
DataContext="{Binding Articles}"
HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}">
<DataTemplate>
<Grid>
<ListView
AutomationProperties.AutomationId="ItemListViewSection3"
AutomationProperties.Name="Items In Group"
SelectionMode="None"
IsItemClickEnabled="True"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource BannerBackgroundArticleTemplate}"
ItemClick="ItemView_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
</ListView>
<TextBlock
x:Name="NoArticlesTextBlock"
HorizontalAlignment="Center"
VerticalAlignment="center"
Style="{StaticResource HeaderTextBlockStyle}"
TextWrapping="WrapWholeWords"
TextAlignment="Center"/>
</Grid>
</DataTemplate>
</HubSection>
我遇到的问题是我无法从 C# 代码访问 TextBlock.有没有更简单的方法来做到这一点?
The problem I'm having is that I can't access the TextBlock from the C# code. Is there an easier way to do this?
推荐答案
我遇到的问题是我无法从 C# 代码访问 TextBlock.
The problem I'm having is that I can't access the TextBlock from the C# code.
是的,因为 TextBlock 是在 DataTemplate 中定义的,所以在应用 DataTemplate 之前,TextBlock 将不可用.因此, x:Name 属性不会在 *.g.i.cs 文件的 InitializeComponent 方法中自动生成变量引用.(阅读XAML Namescopes 了解更多信息).
Yes, since the TextBlock is defined inside a DataTemplate, the TextBlock won't be available until the DataTemplate has been applied. Thus, the x:Name attribute won't automatically generate a variable reference in the InitializeComponent method in your *.g.i.cs file. (Read up on XAML Namescopes for more information).
如果您想从代码隐藏中访问它,有两种方法:
If you want to access it from your code-behind, there are two ways:
第一种方法最简单:您可以在该 TextBlock 的 Loaded 事件处理程序的 sender 参数中获取对该 TextBlock 的引用.
The first way is the simplest: you can get a reference to the TextBlock in the sender argument of the Loaded event handler for that TextBlock.
<TextBlock Loaded="NoArticlesTextBlock_Loaded" />
然后在您的代码隐藏中:
Then in your code-behind:
private TextBlock NoArticlesTextBlock;
private void NoArticlesTextBlock_Loaded(object sender, RoutedEventArgs e)
{
NoArticlesTextBlock = (TextBlock)sender;
}
<小时>
第二种方式是手动遍历可视化树以定位具有所需名称的元素.这样比较适合动态布局,或者当你有很多控件要引用时,这样做会太乱.你可以这样实现:
The second way is to traverse the visual tree manually to locate the element with the required name. This is more suitable for dynamic layouts, or when you have a lot of controls you want to reference that doing the previous way would be too messy. You can achieve it like this:
<Page Loaded="Page_Loaded" ... />
然后在您的代码隐藏中:
Then in your code-behind:
static DependencyObject FindChildByName(DependencyObject from, string name)
{
int count = VisualTreeHelper.GetChildrenCount(from);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(from, i);
if (child is FrameworkElement && ((FrameworkElement)child).Name == name)
return child;
var result = FindChildByName(child, name);
if (result != null)
return result;
}
return null;
}
private TextBlock NoArticlesTextBlock;
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// Note: No need to start searching from the root (this), we can just start
// from the relevant HubSection or whatever. Make sure your TextBlock has
// x:Name="NoArticlesTextBlock" attribute in the XAML.
NoArticlesTextBlock = (TextBlock)FindChildByName(this, "NoArticlesTextBlock");
}
<小时>
这篇关于Windows Phone 8.1 在 DataTemplate 中切换 TextBlock 的可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!