【问题标题】:How to set the visiblility of a grid when the grid is inside a DataTemplate?当网格位于 DataTemplate 内时,如何设置网格的可见性?
【发布时间】:2016-12-19 10:15:57
【问题描述】:

在我们的 UWP 应用中,MyListView 的 DataTemplate 在后面的代码中设置为 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?

【问题讨论】:

    标签: xaml uwp datatemplate uwp-xaml


    【解决方案1】:

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

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

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

    (此方法也可以仅按类型搜索;只需将null 作为名称即可。)

    【讨论】:

      猜你喜欢
      • 2014-12-19
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 2013-06-14
      • 1970-01-01
      • 2014-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多