WPF 按下按钮时更新项目计数

WPF Update count of item when button is pushed

WPF 和此处编程的新手 我正在尝试在按下按钮时更新 ListView 中的项目,如果该项目已存在于该 ListView 中,例如用户输入 CAR 并且 CAR 已经在 ListView 中 CAR计数应该从 1 到 2。

这是我的 InventoryItem class:

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 还是我不理解绑定和事件?

您需要通知 InventoryItem 中的 属性 变化 class 以更新 ListView 中 ItemCount 的变化。

快速解决方案:

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 class 已经包含对 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"/>