Reputation: 39
I have an ItemCart. I would like to show the CartItems in a listview, with ItemName and quantity. When I press a button, the quantity of the item in listView should increase.
My problem: The CartItem of the observableCollection is increased each time i pressed the button correctly, but the UI is not updating/refreshing. Is anyone there who can help me??
Here is the code:
public class AboutViewModel : BaseViewModel
{
public AboutViewModel()
{
AddCartItem = new Command(AddItem);
cartItems = new ObservableCollection<CartItem>();
cartItems.Add(new CartItem { ItemName = "Item1", Quantity = 4 });
cartItems.Add(new CartItem { ItemName = "Item2", Quantity = 2 });
}
public ICommand AddCartItem { get; }
public ObservableCollection<CartItem> cartItems;
public ObservableCollection<CartItem> CartItems
{
get { return cartItems; }
set
{
cartItems = value;
OnPropertyChanged("CartItems");
}
}
void AddItem()
{
cartItems[0].Quantity++;
CartItems = cartItems;
}
}
<StackLayout>
<ListView ItemsSource="{Binding CartItems">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding ItemName, Mode=TwoWay}"
Detail="{Binding Quantity, Mode=TwoWay}"></TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<BoxView
Color="Blue" />
<Button Text="Add Name" Command="{Binding AddCartItem}"/>
Upvotes: 0
Views: 250
Reputation: 13899
If you want to refresh UI once changing the value of property Quantity
in model CartItem
, you need to implement interface INotifyPropertyChanged
for CartItem
.
Based on your code, I have achieved this function, you can refer to the following code:
CartItem.cs
public class CartItem: INotifyPropertyChanged
{
public string ItemName { get; set; }
//public int Quantity { get; set; }
int _quantity;
public int Quantity
{
get => _quantity;
set => SetProperty(ref _quantity, value);
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
AboutViewModel.cs
public class AboutViewModel
{
public AboutViewModel()
{
AddCartItem = new Command(AddItem);
CartItems = new ObservableCollection<CartItem>();
CartItems.Add(new CartItem { ItemName = "Item1", Quantity = 4 });
CartItems.Add(new CartItem { ItemName = "Item2", Quantity = 2 });
}
public ICommand AddCartItem { get; }
public ObservableCollection<CartItem> CartItems { get; set; }
void AddItem()
{
CartItems[0].Quantity++;
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:listviewapp="clr-namespace:ListViewApp"
x:Class="ListViewApp.MainPage">
<ContentPage.BindingContext>
<listviewapp:AboutViewModel></listviewapp:AboutViewModel>
</ContentPage.BindingContext>
<StackLayout>
<ListView ItemsSource="{Binding CartItems}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding ItemName, Mode=TwoWay}"
Detail="{Binding Quantity, Mode=TwoWay}"></TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="Add Name" Command="{Binding AddCartItem}"/>
</StackLayout>
</ContentPage>
Note:
1.In fact, you don't have to define another variable cartItems
at all.
You can only define variable CartItems
:
public ObservableCollection<CartItem> CartItems { get; set; }
2.For document ObservableCollection Class, we know that this class:
Represents a dynamic data collection that provides notifications when items get added or removed, or when the whole list is refreshed.
So, if you add modifiers public ObservableCollection<CartItem>
for variable CartItems
,when you add or remove one or more Items to this list, the UI will be updated. And if you want the UI refresh automatically after you change the value of property Quantity
in model CartItem
, you need to implement interface INotifyPropertyChanged
for CartItem
.
public ObservableCollection<CartItem> CartItems { get; set; }
Upvotes: 1