当网格在DataTemplate中时,如何设置网格的可见性?

时间:2016-12-19 10:15:58

标签: xaml uwp datatemplate uwp-xaml

在我们的UWP应用程序中,DataTemplate for MyListView在Page.Resources中的DataTemplateA或DataTemplateB后面的代码中设置。每个数据模板都包含一个网格(TopGrid),其中包含DisplayGridButton和另一个网格(DisplayGrid)。

DisplayGrid包含SecondListView和HideGridButton

DisplayGridButton应该显示DisplayGrid。 HideGridButton应该折叠DisplayGrid。

XAML

<Page.Resources>
    <DataTemplate x:Key="DataTemplateA">
        <Grid Name="TopGrid">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal">
                <TextBox/>
                <Button Name="DisplayGridButton" Content="Show" Margin="10,0" Click="DisplayGridButton_Click"/>
            </StackPanel>
            <Grid Name="DisplayGrid" Grid.Row="1" Visibility="Collapsed">
                <StackPanel>
                    <Button Name="HideGridButton" Content="Hide" Click="HideGridButton_Click"/>
                    <ListView Name="SecondListView">
                        <ListView.ItemTemplate>
                            <DataTemplate >

                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackPanel>
            </Grid>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="DataTemplateB">
        <Grid Name="TopGrid">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal">
                <TextBox/>
                <Button Name="DisplayGridButton" Content="Show" Margin="10,0" Click="DisplayGridButton_Click"/>
            </StackPanel>
            <Grid Name="DisplayGrid" Grid.Row="1" Visibility="Collapsed">
                <StackPanel>
                    <Button Name="HideGridButton" Content="Hide" Click="HideGridButton_Click"/>
                    <ListView Name="SecondListView">
                        <ListView.ItemTemplate>
                            <DataTemplate >

                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackPanel>
            </Grid>
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView Name="MyListView">

    </ListView>
</Grid>

DataTemplateA或DataTemplateB在后面的代码中设置。

if (condition)
{
    MyListView.ItemTemplate = (DataTemplate)Resources["DataTemplateA"];
}
    else
{
    MyListView.ItemTemplate = (DataTemplate)Resources["DataTemplateB"];
}

在后面的代码中我可以创建事件处理程序,但我无法访问DisplayGrid以使其可见或折叠它。

我通常会设置此类可见性。

 private void DisplayGridButton_Click(object sender, RoutedEventArgs e)
    {
        DisplayGrid.Visibility = Visibility.Visible;
    }

 private void HideGridButton_Click(object sender, RoutedEventArgs e)
    {
        DisplayGrid.Visibility = Visibility.Collapsed;
    }

如何通过按钮单击事件访问DataTemplate中的DisplayGrid?

1 个答案:

答案 0 :(得分:0)

由于网格是在模板中定义的,因此您必须在运行时将其挖掘出来。 (如果您可以将其引用为&#34; DisplayGrid&#34;来自代码隐藏,您无论如何也不会知道它属于哪个列表视图项。)

实现类似这样的点击处理程序:

t1->t->t2

(公平警告:此代码找到适当的父级开始的方式有点脆弱;如果模板更改,它可能会中断。按名称搜索会更好,但我现在没有任何方便的东西。)

以下是在可视化树中查找命名子项的辅助方法:

private void DisplayGridButton_Click(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    StackPanel stackPanel = button?.Parent as StackPanel;
    Grid grid = stackPanel?.Parent as Grid;
    if (grid != null)
    {
        Grid displayGrid = FindVisualChild<Grid>(grid, "DisplayGrid");
        if (displayGrid != null)
        {
            displayGrid.Visibility = Visibility.Visible;
        }
    }
}

private void HideGridButton_Click(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    StackPanel stackPanel = button?.Parent as StackPanel;
    Grid grid = stackPanel?.Parent as Grid;
    if (grid != null)
    {
        grid.Visibility = Visibility.Collapsed;
    }
}

(此方法也可以仅按类型搜索;只需传递public static T FindVisualChild<T>( DependencyObject parent, string name = null) where T : DependencyObject { if (parent != null) { int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { DependencyObject child = VisualTreeHelper.GetChild(parent, i); T candidate = child as T; if (candidate != null) { if (name == null) { return candidate; } FrameworkElement element = candidate as FrameworkElement; if (name == element?.Name) { return candidate; } } T childOfChild = FindVisualChild<T>(child, name); if (childOfChild != null) { return childOfChild; } } } return default(T); } 作为名称。)