Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView not refreshing after adding value in Xamarin Forms

What i am doing is passing data through more than 2 pages. I assign viewmodel to next page while i am navigating. In second page i have a listview that is not refreshing/updating after adding a value.

Help me please!!

Here is my code

MyViewModel

public class MyViewModel : INotifyPropertyChanged
    { 
        public string _userName { get; set; }
        public List<family> familyList;
        public List<family> FamilyList
        {
            get { return familyList; }
            set
            {
                familyList = value;
                OnPropertyChanged();
            }
        }       
        public event PropertyChangedEventHandler PropertyChanged;
        public MyViewModel()
        {
            _userName = "Mak";
            familyList = new List<family>();
        }
        public void AddMember(string memberName)
        {
            FamilyList.Add(new family
            {
                name = memberName,
                id = Guid.NewGuid().ToString(),
                username=_userName
            });
        }
 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
}

userdetails.xaml

<cl:BasePage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="familyinfo.userdetails" xmlns:cl="clr-namespace:familyinfo;assembly=familyinfo">
<Label Font="Roboto-Medium" FontSize="14" Text="{Bindinbg _userName}" />
<Button Clicked="Next_Step" HeightRequest="30" HorizontalOptions="FillAndExpand" BorderRadius="12" Text="NEXT" />
</cl:BasePage>

userdetails.xaml.cs

public partial class userdetails : BasePage
    {
        public MyViewModel _myViewModel { get; set; }
        public userdetails()
        {
            InitializeComponent();
            BindingContext = new MyViewModel();
        }
        void Next_Step(object sender, System.EventArgs e)
        {
            _myViewModel =(MyViewModel) this.BindingContext;
            var familyMember = new FamilyMember();
            familyMember.BindingContext = _myViewModel;
            Application.Current.MainPage = new NavPage(registerCar);
         }
     }

FamilyMember.xaml

 <cl:BasePage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="familyinfo.FamilyMember" xmlns:cl="clr-namespace:familyinfo;assembly=familyinfo">
    <Label Font="Roboto-Medium" FontSize="14" Text="{Bindinbg _userName}" />
<cl:CustomEntry x:Name="txtMemberName" Placeholder="Member Name" FontSize="12" /> 
<Button Clicked="AddMember" HeightRequest="30" HorizontalOptions="FillAndExpand" BorderRadius="12" Text="Add" />
<ListView ItemsSource="{Binding FamilyList}" VerticalOptions="FillAndExpand" BackgroundColor="Transparent">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <Grid Padding="20,10,0,0" ColumnSpacing="12" RowSpacing="0" BackgroundColor="Transparent">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto">
                                        </ColumnDefinition>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto">
                                        </RowDefinition>
                                    </Grid.RowDefinitions>
                                    <Label Grid.Row="0" Text="{Binding name}" Grid.Column="0" Font="Roboto-Medium" FontSize="14" TextColor="#000000" />
                                </Grid>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    </cl:BasePage>

FamilyMember.xaml.cs

public partial class FamilyMember : BasePage
    {
        public MyViewModel _myViewModel { get; set; }
        public userdetails()
        {
            InitializeComponent();
        }
         void AddMember(object sender, System.EventArgs e)
        {
         _myViewModel = (MyViewModel)this.BindingContext;
        _myViewModel.AddMember(txtMemberName.Text);
        }
     }
like image 699
Atul Avatar asked Sep 02 '25 02:09

Atul


2 Answers

I agree with Atul: Using an ObservableCollection is the right way to do it.

A workaround - if you don't have a chance to change that - is to set the ListView's ItemSource to null and back to the list, whenever data changed and the UI needs to update:

void UpdateListView(ListView listView)
{
    var itemsSource = listView.ItemsSource;
    listView.ItemsSource = null;
    listView.ItemsSource = itemsSource;
}
like image 162
Falko Avatar answered Sep 04 '25 15:09

Falko


In fact, you must use a collection that implements INotifyCollectionChanged interface (instead of the well known INofifyPropertyChanged). And that's exactly what does ObservableCollection<T> for you. This is why it works like "magic".

like image 43
TaiT's Avatar answered Sep 04 '25 15:09

TaiT's