Home > OS >  C# WinUI3 Desktop: How can I reference or control a button in a ListView's selected item DataTe
C# WinUI3 Desktop: How can I reference or control a button in a ListView's selected item DataTe

Time:03-03

I have a ListView:

                <ListView  x:Name="All_Staging_ListView"
                           SelectionMode="Single"
                           SelectionChanged="All_Staging_ListView_SelectionChanged"      
                           ItemTemplate="{StaticResource All_Staging_ListView_Template}"
                           BorderThickness="3"
                           BorderBrush="#005986"
                           HorizontalAlignment="Stretch"/>

I have a DataTemplate for the ListView:

<Page.Resources>
    <DataTemplate x:Key="All_Staging_ListView_Template" x:DataType="local1:All_Staging_Data_Collection_ViewEdit">
        <Border BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Bind Metric_ID}" x:Phase="1" FontWeight="ExtraBold" Margin="0,0,5,0"/>
                <TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{x:Bind Period}" Margin="0,0,0,0"/>
                <TextBlock Grid.Row="0" Grid.Column="3" Text="{x:Bind ID}" Margin="25,0,0,0"/>
                <Button Grid.Row="0" Grid.RowSpan="2" Grid.Column="4" x:Name="ButtonListViewEdit" Content="Edit this metric" Margin="20,0,0,0" Visibility="Collapsed" Click="ButtonListViewEdit_Click"/>
                <TextBlock Grid.Row="1" Grid.Column="0" Text="Name:" FontWeight="Bold" />
                <TextBlock Grid.Row="1" Grid.Column="1" Text="{x:Bind Metric_Name}" x:Phase="1" Margin="0,0,20,0"/>
                <TextBlock Grid.Row="1" Grid.Column="2" Text="Product:" FontWeight="Bold"/>
                <TextBlock Grid.Row="1" Grid.Column="3" Text="{x:Bind Product}"/>
                <TextBlock Grid.Row="2" Grid.Column="0" Text="Definition:" FontWeight="Bold"/>
                <TextBlock Grid.Row="2" Grid.Column="1" Text="{x:Bind Metric_Definition}" x:Phase="1" Margin="0,0,20,0"/>
                <TextBlock Grid.Row="2" Grid.Column="2" Text="Company:" FontWeight="Bold" />
                <TextBlock Grid.Row="2" Grid.Column="3" Text="{x:Bind Company}"/>
                <TextBlock Grid.Row="3" Grid.Column="0" Text="Goal:" FontWeight="Bold"/>
                <TextBlock Grid.Row="3" Grid.Column="1" Text="{x:Bind Goal_Description}" x:Phase="1" Margin="0,0,20,0"/>
                <TextBlock Grid.Row="3" Grid.Column="2" Text="System:" FontWeight="Bold"/>
                <TextBlock Grid.Row="3" Grid.Column="3" Text="{x:Bind System}"/>
            </Grid>
        </Border>
    </DataTemplate>
</Page.Resources>

When an item in the ListView is 'selected' I would like to make the button 'ButtonListViewEdit' visible!!!!! Edit: (I would like to make the button in the selected item visible only, not in the other unselected items in the ListView).

I don't know the syntax to reference the button within the datatemplate in the 'SelectionChanged' event handler:

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

I am able to access the values of the bound textblocks, but not the button (to make it visible).

Thank you members of stackoverflow for you help in advance.

CodePudding user response:

Bind the Visibility property of the Button to a property of your All_Staging_Data_Collection_ViewEdit class or get a reference to the Button using the VisualTreeHelper class in your event handler:

private void All_Staging_ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    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;
}
  • Related