CollectionView UI not updated when Switch Toggled but ObservableCollection updated

Mohanasundharam Murugan 20 Reputation points
2023-01-24T19:30:26.5+00:00

Here, when toggle, observablecollection has been updated, but ui not updated.

Expected Output is: When switch toggle is on, the items pack price need to be display. When switch toggle is off, the item's price need to be display.

<CollectionView x:Name="GroceryCollectionView" ItemsSource="{Binding GroceryItemsList}">
	<CollectionView.ItemTemplate>
		<DataTemplate>
			<Frame Padding="0" BorderColor="LightGray" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
				<StackLayout Spacing="0" Orientation="Vertical">
					
						<Label IsVisible="{Binding PricePerItemVisibility}">
							<Label.FormattedText>
								<FormattedString>
									<Span Text="Rs. "></Span>
									<Span Text="{Binding PricePerItem}"></Span>
								</FormattedString>
							</Label.FormattedText>
						</Label>
						<Label IsVisible="{Binding PricePerPackVisibility}">
							<Label.FormattedText>
								<FormattedString>
									<Span Text="Rs. "></Span>
									<Span Text="{Binding PricePerPack}"></Span>
								</FormattedString>
							</Label.FormattedText>
						</Label>
						<Switch x:Name="PriceToggle" Toggled="PriceToggle_Toggled" OnColor="{StaticResource AppTheme}" ThumbColor="Black" HorizontalOptions="EndAndExpand"></Switch>
					</StackLayout>
				</StackLayout>
			</Frame>
		</DataTemplate>
	</CollectionView.ItemTemplate>
</CollectionView>




public class GroceryBO
{
	public int ItemID { get; set; }
	public string ItemName { get; set; }
	public string ItemDescription { get; set; }
	public string ItemCoverImage { get; set; }
	public double PricePerItem { get; set; }
	public double PricePerPack { get; set; }
	public bool PricePerItemVisibility { get; set; }
	public bool PricePerPackVisibility { get; set; }
}



private void PriceToggle_Toggled(object sender, ToggledEventArgs e)
{
	try
	{
		var x = sender as Switch;
		var getToggledItem = (GroceryBO)getMenuList.BindingContext;
		var currList = itemDetailScreenViewModel.GroceryItemsList;//Data Initially bind from ViewModel

		foreach (var x in currList.Where(w=>w.ItemID==getToggledItem.ItemID))
		{
			if (e.Value)
			{
				x.PricePerItemVisibility = false;
				x.PricePerPackVisibility = true;
			}
			else
			{
				x.PricePerItemVisibility = true;
				x.PricePerPackVisibility = false;
			}
		}
		itemDetailScreenViewModel.GroceryItemsList=currList;
		GroceryCollectionView.ItemsSource = currList;
	}
	catch(Exception ex)
	{
		//
	}
}


Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,294 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,245 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
765 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,571 Reputation points Microsoft Vendor
    2023-01-25T02:53:43.57+00:00

    Hello,

    You can do this by implement INotifyPropertyChanged interface for your GroceryBO.cs firstly. Then, please achieve OnPropertyChanged method as well for your properies, I make a test for PricePerItemVisibility and PricePerPackVisibility, you can achieve OnPropertyChanged method for other properties, please refer to the following code.

    public class GroceryBO: INotifyPropertyChanged    {
                   public int ItemID { get; set; }
            public string ItemName { get; set; }
            public string ItemDescription { get; set; }
            public string ItemCoverImage { get; set; }
            public double PricePerItem { get; set; }
            public double PricePerPack { get; set; }
            bool pricePerItemVisibility=true, pricePerPackVisibility=false;
            public bool PricePerItemVisibility
            {
                set
                {
                    if (pricePerItemVisibility != value)
                    {
                        pricePerItemVisibility = value;
                        OnPropertyChanged("PricePerItemVisibility");
                    }
                }
                get
                {
                    return pricePerItemVisibility;
                }
            }
            public bool PricePerPackVisibility
            {
                set
                {
                    if (pricePerPackVisibility != value)
                    {
                        pricePerPackVisibility = value;
                        OnPropertyChanged("PricePerPackVisibility");
                    }
                }
                get
                { 
                   return pricePerPackVisibility;
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    

    If you achieve the mvvm, you can operate object directly, no need to get all of items in the observablecollection then re-set it, I change your code in PriceToggle_Toggled method, you can change the value of object directly.

    private void PriceToggle_Toggled(object sender, ToggledEventArgs e)
            {
                try
                {
                    var swx = sender as Switch;
                    var x = (GroceryBO)swx.BindingContext;
                    if (e.Value)
                        {
                            x.PricePerItemVisibility = false;
                            x.PricePerPackVisibility = true;
                        }
                        else
                        {
                            x.PricePerItemVisibility = true;
                            x.PricePerPackVisibility = false;
                        }
                }
                catch (Exception ex)
                {            }
            }
    
    
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Mohanasundharam Murugan 20 Reputation points
    2023-01-25T06:18:15.31+00:00

    Thank you very much Leon Lu (Shanghai Wicresoft Co,.Ltd.).

    It's working fine!

    0 comments No comments