C# WinUI3 Desktop:如何在 ListView 的选定项 DataTemplate 中引用或控制两个按钮?
C# WinUI3 Desktop: How can I reference or control two buttons in a ListView's selected item DataTemplate?
我在列表视图数据模板中有两个按钮。 'ButtonListViewEdit' 和 'ButtonListViewDelete'。
我希望这两个按钮保持 'collapsed' 直到选择列表视图项。只有所选列表视图项目上的按钮应该可见。
<Page.Resources>
<DataTemplate x:Key="All_Staging_ListView_Template" x:DataType="local1:All_Staging_Data_Collection_ViewEdit">
<Border BorderBrush="Aqua" BorderThickness="0 0 0 2" Padding="10,3" Margin="0,0,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="190"/>
<ColumnDefinition MinWidth="90"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Bind Metric_ID}" x:Phase="1" FontWeight="ExtraBold" Margin="0,0,0,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="6" Text="{x:Bind Metric_Name}" x:Phase="1" Margin="0,0,20,0"/>
<TextBlock Grid.Row="0" Grid.Column="4" Text="{x:Bind ID}" Visibility="Collapsed" Margin="0,0,0,0"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Period" FontWeight="Medium" FontSize="13" x:Name="MasterFontSize"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{x:Bind Period}" FontSize="13"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding Path=Denominator_Ref}" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="1" Grid.Column="3" Text="{Binding Path=Denominator}" TextAlignment="Right" FontSize="13" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="Product" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{x:Bind Product}" FontSize="13"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="{Binding Path=Numerator_Ref}" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="2" Grid.Column="3" Text="{Binding Path=Numerator}" TextAlignment="Right" FontSize="13"/>
<StackPanel Grid.Row="2" Grid.Column="6" Orientation="Horizontal" Margin="20,0,0,0">
<Button x:Name="ButtonListViewEdit" Content="✏" Margin="0,0,0,0" Visibility="Collapsed" Click="ButtonListViewEdit_Click" Padding="1" FontSize="10" BorderBrush="Transparent" ToolTipService.ToolTip="Re-enter metric results" Background="Transparent"/>
<Button x:Name="ButtonListViewDelete" Content="" Margin="0,0,0,0" Visibility="Visible" Click="ButtonListViewDelete_Click" Padding="1" FontFamily="Segoe MDL2 Assets" BorderBrush="Transparent" ToolTipService.ToolTip="Remove selected metric results" Background="Transparent"/>
</StackPanel>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Company" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{x:Bind Company}" FontSize="13"/>
<TextBlock Grid.Row="3" Grid.Column="2" Text="{Binding Path=Total_Ref}" FontWeight="Medium" FontSize="13" />
<TextBlock Grid.Row="3" Grid.Column="3" Text="{Binding Path=Total}" TextAlignment="Right" FontSize="13" />
<TextBlock Grid.Row="3" Grid.Column="6" Text="Entered by" FontWeight="Medium" FontSize="13" Margin="20,0,10,0"/>
<TextBlock Grid.Row="3" Grid.Column="7" Text="{x:Bind Insert_User_Name}" FontSize="13"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="State" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="4" Grid.Column="1" Text="{x:Bind State}" FontSize="13"/>
<TextBlock Grid.Row="4" Grid.Column="6" Text="Entered Date" FontWeight="Medium" FontSize="13" Margin="20,0,10,0" />
<TextBlock Grid.Row="4" Grid.Column="7" Text="{x:Bind Insert_Date}" FontSize="13"/>
</Grid>
</Border>
</DataTemplate>
</Page.Resources>
贡献者 mm8 在我的 ListView DataTemplate 中只有一个按钮时帮助了我,mm8 向我展示了 'getting a reference to the Button using the VisualTreeHelper class in your event handler:'
的解决方案
我成功实现了mm8的解决方案。此处显示:
private void All_Staging_ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
All_Staging_Data_Collection_ViewEdit listitem = new All_Staging_Data_Collection_ViewEdit();
listitem = (All_Staging_Data_Collection_ViewEdit)All_Staging_ListView.SelectedItem;
Debug.WriteLine($"ListView >>>>>>>>>>>>>>>>>>>>>>>>>>>>> SelectionChanged > Metric ID: {listitem.Metric_ID}, ID: {listitem.ID}");
foreach (object selectedItem in e.AddedItems)
DisplayOrHideButton(selectedItem, true);
foreach (object selectedItem in e.RemovedItems)
DisplayOrHideButton(selectedItem, false);
}
private void DisplayOrHideButton(object item, bool display)
{
ListViewItem container = All_Staging_ListView.ContainerFromItem(item) as ListViewItem;
if (container != null)
{
Button button = FindVisualChild<Button>(container);
if (button != null)
button.Visibility = display ? Visibility.Visible : Visibility.Collapsed;
}
}
private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T t)
return t;
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
应该如何修改此解决方案,以便当用户选择列表项时,我添加的新的第二个按钮也可以显示?
谢谢 mm8 和 Whosebug。
此致
以下代码应该找到模板中的所有按钮,并在选择或取消选择项目时显示或隐藏它们:
private void DisplayOrHideButton(object item, bool display)
{
ListViewItem container = All_Staging_ListView.ContainerFromItem(item) as ListViewItem;
if (container != null)
{
IEnumerable<Button> buttons = FindVisualChildren<Button>(container);
if (buttons != null)
foreach (Button button in buttons)
button.Visibility = display ? Visibility.Visible : Visibility.Collapsed;
}
}
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject obj) where T : DependencyObject
{
if (obj == null)
yield return (T)Enumerable.Empty<T>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child == null)
continue;
if (child is T t)
yield return t;
foreach (T childOfChild in FindVisualChildren<T>(child))
yield return childOfChild;
}
}
我在列表视图数据模板中有两个按钮。 'ButtonListViewEdit' 和 'ButtonListViewDelete'。 我希望这两个按钮保持 'collapsed' 直到选择列表视图项。只有所选列表视图项目上的按钮应该可见。
<Page.Resources>
<DataTemplate x:Key="All_Staging_ListView_Template" x:DataType="local1:All_Staging_Data_Collection_ViewEdit">
<Border BorderBrush="Aqua" BorderThickness="0 0 0 2" Padding="10,3" Margin="0,0,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="190"/>
<ColumnDefinition MinWidth="90"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Bind Metric_ID}" x:Phase="1" FontWeight="ExtraBold" Margin="0,0,0,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="6" Text="{x:Bind Metric_Name}" x:Phase="1" Margin="0,0,20,0"/>
<TextBlock Grid.Row="0" Grid.Column="4" Text="{x:Bind ID}" Visibility="Collapsed" Margin="0,0,0,0"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Period" FontWeight="Medium" FontSize="13" x:Name="MasterFontSize"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{x:Bind Period}" FontSize="13"/>
<TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding Path=Denominator_Ref}" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="1" Grid.Column="3" Text="{Binding Path=Denominator}" TextAlignment="Right" FontSize="13" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="Product" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{x:Bind Product}" FontSize="13"/>
<TextBlock Grid.Row="2" Grid.Column="2" Text="{Binding Path=Numerator_Ref}" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="2" Grid.Column="3" Text="{Binding Path=Numerator}" TextAlignment="Right" FontSize="13"/>
<StackPanel Grid.Row="2" Grid.Column="6" Orientation="Horizontal" Margin="20,0,0,0">
<Button x:Name="ButtonListViewEdit" Content="✏" Margin="0,0,0,0" Visibility="Collapsed" Click="ButtonListViewEdit_Click" Padding="1" FontSize="10" BorderBrush="Transparent" ToolTipService.ToolTip="Re-enter metric results" Background="Transparent"/>
<Button x:Name="ButtonListViewDelete" Content="" Margin="0,0,0,0" Visibility="Visible" Click="ButtonListViewDelete_Click" Padding="1" FontFamily="Segoe MDL2 Assets" BorderBrush="Transparent" ToolTipService.ToolTip="Remove selected metric results" Background="Transparent"/>
</StackPanel>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Company" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{x:Bind Company}" FontSize="13"/>
<TextBlock Grid.Row="3" Grid.Column="2" Text="{Binding Path=Total_Ref}" FontWeight="Medium" FontSize="13" />
<TextBlock Grid.Row="3" Grid.Column="3" Text="{Binding Path=Total}" TextAlignment="Right" FontSize="13" />
<TextBlock Grid.Row="3" Grid.Column="6" Text="Entered by" FontWeight="Medium" FontSize="13" Margin="20,0,10,0"/>
<TextBlock Grid.Row="3" Grid.Column="7" Text="{x:Bind Insert_User_Name}" FontSize="13"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="State" FontWeight="Medium" FontSize="13"/>
<TextBlock Grid.Row="4" Grid.Column="1" Text="{x:Bind State}" FontSize="13"/>
<TextBlock Grid.Row="4" Grid.Column="6" Text="Entered Date" FontWeight="Medium" FontSize="13" Margin="20,0,10,0" />
<TextBlock Grid.Row="4" Grid.Column="7" Text="{x:Bind Insert_Date}" FontSize="13"/>
</Grid>
</Border>
</DataTemplate>
</Page.Resources>
贡献者 mm8 在我的 ListView DataTemplate 中只有一个按钮时帮助了我,mm8 向我展示了 'getting a reference to the Button using the VisualTreeHelper class in your event handler:'
的解决方案我成功实现了mm8的解决方案。此处显示:
private void All_Staging_ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
All_Staging_Data_Collection_ViewEdit listitem = new All_Staging_Data_Collection_ViewEdit();
listitem = (All_Staging_Data_Collection_ViewEdit)All_Staging_ListView.SelectedItem;
Debug.WriteLine($"ListView >>>>>>>>>>>>>>>>>>>>>>>>>>>>> SelectionChanged > Metric ID: {listitem.Metric_ID}, ID: {listitem.ID}");
foreach (object selectedItem in e.AddedItems)
DisplayOrHideButton(selectedItem, true);
foreach (object selectedItem in e.RemovedItems)
DisplayOrHideButton(selectedItem, false);
}
private void DisplayOrHideButton(object item, bool display)
{
ListViewItem container = All_Staging_ListView.ContainerFromItem(item) as ListViewItem;
if (container != null)
{
Button button = FindVisualChild<Button>(container);
if (button != null)
button.Visibility = display ? Visibility.Visible : Visibility.Collapsed;
}
}
private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T t)
return t;
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
应该如何修改此解决方案,以便当用户选择列表项时,我添加的新的第二个按钮也可以显示?
谢谢 mm8 和 Whosebug。 此致
以下代码应该找到模板中的所有按钮,并在选择或取消选择项目时显示或隐藏它们:
private void DisplayOrHideButton(object item, bool display)
{
ListViewItem container = All_Staging_ListView.ContainerFromItem(item) as ListViewItem;
if (container != null)
{
IEnumerable<Button> buttons = FindVisualChildren<Button>(container);
if (buttons != null)
foreach (Button button in buttons)
button.Visibility = display ? Visibility.Visible : Visibility.Collapsed;
}
}
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject obj) where T : DependencyObject
{
if (obj == null)
yield return (T)Enumerable.Empty<T>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child == null)
continue;
if (child is T t)
yield return t;
foreach (T childOfChild in FindVisualChildren<T>(child))
yield return childOfChild;
}
}