WedX - журнал о программировании и компьютерных науках

WPF Обновить количество элементов при нажатии кнопки

новичок в WPF и программировании здесь. Я пытаюсь обновить элемент в ListView при нажатии кнопки, если элемент уже существует в этом ListView, например, пользователь вводит CAR, а CAR уже находится в ListView, количество CAR должно начинаться с 1 до 2.

Это мой класс InventoryItem:

public class InventoryItem
    {
        public string Name { get; set; }
        public int Count { get; set; }
    }

Вот моя ViewModel

public class ViewModel : ViewModelBase
    {

        private InventoryItem _item;
        private int _count;
        private ObservableCollection<InventoryItem> _inventoryItems;
        private ICommand _addItem;

        public InventoryItem Item
        {
            get 
            {
                return _item;
            }
            set
            {
                _item = value;
                NotifyPropertyChanged("Item");
            }
        }

        public int Count
        {
            get { return _count; }
            set { _count = value; NotifyPropertyChanged("Count"); }
        }

        public ObservableCollection<InventoryItem> InventoryItems
        {
            get
            {
                return _inventoryItems;
            }
            set
            {
                _inventoryItems = value;
                NotifyPropertyChanged("Items");
            }
        }

        public ICommand AddItem
        {
            get
            {
                if (_addItem == null)
                {
                    _addItem = new RelayCommand(ParamArrayAttribute => this.Submit(), null);
                }
                return _addItem;
            }
        }

        public ViewModel()
        {
            Item = new InventoryItem();
            InventoryItems = new ObservableCollection<InventoryItem>();
            InventoryItems.CollectionChanged += new NotifyCollectionChangedEventHandler(InventoryItems_CollectionChanged);
        }

        void InventoryItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            NotifyPropertyChanged("Items");
            NotifyPropertyChanged("Count");
        }

        private void Submit()
        {
            if (InventoryItems.Any(p => p.Name == Item.Name))
            {
                InventoryItems.First(x => x.Name == Item.Name).ItemCount++;
            }
            else
            {
                InventoryItems.Add(Item);
            }
        }
    }

Вот мой взгляд

<ListView x:Name="listBox" ItemsSource="{Binding InventoryItems}" Grid.Row="0" HorizontalAlignment="Stretch" Height="Auto" Margin="10,10,10,60" VerticalAlignment="Stretch">
            <ListView.Resources>
                <Style TargetType="GridViewColumnHeader">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Name}" Width="Auto"/>
                    <GridViewColumn DisplayMemberBinding="{Binding ItemCount}" Width="Auto"/>
                </GridView>
            </ListView.View>
        </ListView>

Всякий раз, когда элемент, существующий в списке, вводится, кажется, что InventoryItems ObservableCollection обновляется, однако событие InventoryItems_CollectionChanged не запускается, поэтому ListView не обновляется. Разве коллекция не меняется, так что событие должно запускаться для обновления ListView, или я не понимаю привязку и событие?


  • Используйте nameof в своем свойстве уведомления об изменении. Тогда вы не будете случайно использовать неправильную строку для изменения свойства. Как ты сейчас. Items не является названием вашей собственности 11.01.2021

Ответы:


1

Вам необходимо уведомлять об изменениях свойств в классе InventoryItem, чтобы обновлять изменения ItemCount в ListView.

Быстрое решение:

public class InventoryItem : ViewModelBase
{
    public string Name
    {
        get { return _name; }
        set 
        {
            if (_name != value)
            {
                _name = value;
                NotifyPropertyChanged(nameof(Name));
            }
        }
    }
    private string _name;

    public int ItemCount
    {
        get { return _itemCount; }
        set { _itemCount = value; NotifyPropertyChanged(nameof(ItemCount));
        }
    }
    private int _itemCount;
}

}

Класс ObservableCollection уже содержит обработку INotifyCollectionChanged.

Эта строка нужна только для ObservableCollection. Вы можете удалить все остальное, что связано с InventoryItems и коллекцией в вашей ViewModel.

    public ObservableCollection<InventoryItem> InventoryItems { get; } = new ObservableCollection<InventoryItem>();

Также: когда вы добавляете элемент в коллекцию, вам нужно создать новый элемент. В противном случае вы добавляете тот же объект, который не будет работать.

Это моя уменьшенная ViewModel, как я думаю, вы хотите, чтобы она работала:

public class ViewModel : ViewModelBase
{
    private ICommand _addItem;

    public string InputName
    {
        get { return _inputName; }
        set
        {
            if (_inputName != value)
            {
                _inputName = value;
                NotifyPropertyChanged(nameof(InputName));
            }
        }
    }
    private string _inputName;

    public ObservableCollection<InventoryItem> InventoryItems { get; } = new ObservableCollection<InventoryItem>();

    public ICommand AddItem
    {
        get
        {
            if (_addItem == null)
            {
                _addItem = new RelayCommand(ParamArrayAttribute => this.Submit(), null);
            }
            return _addItem;
        }
    }

    private void Submit()
    {
        if (InventoryItems.Any(p => p.Name == InputName))
        {
            InventoryItems.First(x => x.Name == InputName).ItemCount++;
        }
        else
        {
            InventoryItems.Add(new InventoryItem() { Name = InputName, ItemCount = 1 });
        }
    }
}

Для полноты картины я добавил следующий XAML для теста:

        <TextBox Text="{Binding InputName}" MinWidth="100" Margin="5"/>
        <Button Content="Add" Command="{Binding AddItem}" Margin="5"/>
11.01.2021
  • Для вашей ViewModelBase: посмотрите на этот вопрос. Найдите SetProperty в ответе. Это сделает вашу недвижимость намного чище. stackoverflow.com/questions/36149863 / 11.01.2021
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]