0

I created a WPF Listview and is populated with instances of ProductCategory.

public class ProductCategory
{
    public int Id { get; set; }

    public string CategoryName { get; set; }

    public DateTime CreatedDate { get; set; }

    public DateTime LastUpdated { get; set; }
}

Next I create the list, populate it and assign it to the Listview control.

private List myProductList = new List();

// add some items to myProductList

// assign product list to ItemsSource property of a ListView

myListView.ItemsSource = myProductList;

In the XAML code, a button labelled "Edit" is added to each row. Each row represents an instance of ProductCategory:

    <ListView x:Name="myListView" Height="352" HorizontalAlignment="Left" Margin="20,90,0,0" VerticalAlignment="Top" Width="1008">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Category Name" DisplayMemberBinding="{Binding CategoryName}" Width="200"/>
                <GridViewColumn Header="Created Date" DisplayMemberBinding="{Binding CreatedDate}" Width="200"/>
                <GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding LastUpdated}" Width="200"/>
                <GridViewColumn Header="Edit" Width="200">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="Edit" Click="EditCategory" CommandParameter="{Binding}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

When the user clicks the button, a dialog appears and the user can edit the data for an instance of ProductCategory. When the user closes the dialog, the user is returned to the Listview.

At this point I want to disable all the buttons in the Listview. How could I programmatically achieve this goal?

The buttons are not accessible in myListView.ItemsSource.

user2949159
  • 31
  • 1
  • 3

2 Answers2

0

From the suggested solutions, here is the code to solve my problem:

    private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);

            if (child != null && child is childItem)
            {
                return (childItem)child;
            }
            else
            {
                childItem childOfChild = FindVisualChild<childItem>(child);

                if (childOfChild != null)
                {
                    return childOfChild;
                }
            }
        }
        return null;
    }

    private void disableEditButtonsInListView()
    {
        myListView.Items.Cast<dynamic>().ToList().ForEach(item =>
        {
            var myListViewItem = (ListViewItem)(myListView.ItemContainerGenerator.ContainerFromItem(item));
            Button editButton = FindVisualChild<Button>(myListViewItem);
            if (editButton != null)
            {
                editButton.IsEnabled = false;
            }
        });
    }
user2949159
  • 31
  • 1
  • 3
-1

This is very easy to do using MVVM.
I'm showing a simple example - it breaks MVVM somewhat, but will give you an idea of how it should work.

using Simplified;
using System;
using System.Collections.ObjectModel;
using System.Windows;

namespace Core2022.SO.user2949159
{
    public class ProductsViewModel : BaseInpc
    {
        public ObservableCollection<ProductCategory> Products { get; } = new()
        {
            new ProductCategory() {Id = 1, CategoryName = "Electronics", CreatedDate = DateTime.Now.AddDays(-15).Date, LastUpdated= DateTime.Now.AddDays(-5).Date},
            new ProductCategory() {Id = 2, CategoryName = "Сlothes", CreatedDate = DateTime.Now.AddDays(-7).Date, LastUpdated= DateTime.Now.AddDays(-1).Date}
        };

        private RelayCommand? _editCommand;
        private bool _editingOff;

        public RelayCommand EditCommand => _editCommand ??= new RelayCommand<ProductCategory>(EditExecute, EditCanExecute);

        public bool EditingOff
        {
            get => _editingOff;
            set
            {
                if (Set(ref _editingOff, value))
                    EditCommand.RaiseCanExecuteChanged();
            }
        }
        private bool EditCanExecute(ProductCategory product) => !EditingOff;

        private void EditExecute(ProductCategory product)
        {
            // Some Code for edit product
            MessageBox.Show($"{product.Id}: {product.CategoryName}");
        }
    }
<Window x:Class="Core2022.SO.user2949159.ProductsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Core2022.SO.user2949159"
        mc:Ignorable="d"
        Title="ProductsWindow" Height="450" Width="800"
        DataContext="{DynamicResource vm}">
    <Window.Resources>
        <local:ProductsViewModel x:Key="vm"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <CheckBox Content="Editing Off" IsChecked="{Binding EditingOff}" Margin="5"/>
        <ListView Grid.Row="1" ItemsSource="{Binding Products}" HorizontalAlignment="Left" Margin="20">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Category Name" DisplayMemberBinding="{Binding CategoryName}" Width="200"/>
                    <GridViewColumn Header="Created Date" DisplayMemberBinding="{Binding CreatedDate}" Width="200"/>
                    <GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding LastUpdated}" Width="200"/>
                    <GridViewColumn Header="Edit" Width="200">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Edit"
                                        CommandParameter="{Binding}"
                                        Command="{Binding EditCommand, Mode=OneWay, Source={StaticResource vm}}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

BaseInpc and RelayCommand classes.

EldHasp
  • 6,079
  • 2
  • 9
  • 24