Windows Phone 8.1 中如何在 DataTemplate 中切换 TextBlock 的可见性

3

我正在构建一个Windows Phone 8.1中心应用程序。其中一个中心部分包含一个ListView,显示文章列表。我想在这个中心部分添加一个Textblock,当文章下载失败时显示一条消息。XAML代码如下:

<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。是否有更简单的方法?
1个回答

10

我遇到的问题是,我无法从C#代码中访问TextBlock。

是的,因为TextBlock被定义在DataTemplate内部,所以在应用DataTemplate之前,TextBlock将不可用。因此,在您的*.g.i.cs文件的InitializeComponent方法中,x:Name属性不会自动生成变量引用。(请阅读XAML Namescopes了解更多信息)。

如果您想从代码后台访问它,有两种方法:

第一种方法是最简单的:您可以在TextBlock的Loaded事件处理程序的sender参数中获取对TextBlock的引用。

<TextBlock Loaded="NoArticlesTextBlock_Loaded" />

然后在你的代码后台:

private TextBlock NoArticlesTextBlock;

private void NoArticlesTextBlock_Loaded(object sender, RoutedEventArgs e)
{
    NoArticlesTextBlock = (TextBlock)sender;
}

第二种方法是手动遍历可视树,以定位具有所需名称的元素。这更适用于动态布局,或者当您要引用许多控件时,如果使用先前的方法会太混乱。您可以像这样实现它:
<Page Loaded="Page_Loaded" ... />

然后在你的代码后台:

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");
}

Jerry Nixon在他的博客上有一篇关于此的好文章。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接