当网格在 DataTemplate 中时如何设置网格的可见性?
How to set the visiblility of a grid when the grid is inside a DataTemplate?
在我们的 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?
由于网格是在模板中定义的,因此您必须在运行时将其挖掘出来。 (如果您可以从代码隐藏中将其引用为 "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
作为名称传递即可。)
在我们的 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?
由于网格是在模板中定义的,因此您必须在运行时将其挖掘出来。 (如果您可以从代码隐藏中将其引用为 "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
作为名称传递即可。)