Home > Blockchain >  New elements added to ObservableCollection from external Page are not persisted
New elements added to ObservableCollection from external Page are not persisted

Time:09-24

I have two pages. On the first I want to see every elements from ObservableCollection and the second I want to add new element to ObservableCollection. When I give breakpoint I see that the ObservableCollection has new element, but when I back to the first page new element dosen't exist. What should I do?

There is code

        public ListViewFlascardViewModel()
    {
        GoToAddFlashcard = new Command(goToAddFlashcard);
        Fiszka = new ObservableCollection<Flashcard>();
        Fiszka.Add(new Flashcard {Name = "hello" });         
    }
    
    
    public Command GoToAddFlashcard { get; }
    Flashcard flashcard = new Flashcard();        

    async void goToAddFlashcard()
    {
        await Shell.Current.GoToAsync(nameof(View.NoweFiszki));;            
    }

    public ObservableCollection<Flashcard> Fiszka { get; set; }
}

And there is second page:

 class NoweFiszkiViewModel
{
    public Command SaveFlashcard { get; }
    public NoweFiszkiViewModel()
    {
       
        SaveFlashcard = new Command(save);
    }


    ListViewFlascardViewModel list = new ListViewFlascardViewModel();
   

    private async void save()
    {
        list.Fiszka.Add(new Flashcard { Name = "Bye" });            
         await Shell.Current.GoToAsync("..");
    }
}

I try a lot of things, but nothing help. I am new in C# and I will be appreciated for every help.

I add whole code.

There is view

ListViewFlashcard

<ContentPage 
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
xmlns:viewmodels="clr-namespace:MVVM.ViewModel" 
xmlns:model="clr-namespace:MVVM.Model"
x:Class="MVVM.View.ListViewFlashcard"   
x:DataType="viewmodels:ListViewFlascardViewModel"
>

<ContentPage.BindingContext>
    <viewmodels:ListViewFlascardViewModel/>        
</ContentPage.BindingContext>
<StackLayout>
    
    <Button 
            Command="{Binding GoToAddFlashcard}"
            Text="Click Me"/>
    
    <ListView
        ItemsSource="{Binding Fiszka}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="model:Flashcard">
                <TextCell Text="{Binding Name}"/>
            </DataTemplate>
        </ListView.ItemTemplate>

    </ListView>        
</StackLayout>

NoweFiszki

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         xmlns:viewmodels="clr-namespace:MVVM.ViewModel"
         x:Class="MVVM.View.NoweFiszki">
<ContentPage.BindingContext>
    <viewmodels:NoweFiszkiViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
    <StackLayout>
        <Entry Text="{Binding Text, Mode=TwoWay}"/>
        <Button Text="Save"
                Command="{Binding SaveFlashcard}"/>
    </StackLayout>
</ContentPage.Content>

And Model

Flashcard

    public class Flashcard
{
    public string Name { get; set; }
}

And AppShell

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="MVVM.AppShell"
   xmlns:local="clr-namespace:MVVM.View"
   >   
<FlyoutItem Title="Add Flashcard" Icon="icon_about.png">
    <ShellContent ContentTemplate="{DataTemplate local:ListViewFlashcard}"/>
</FlyoutItem>
    public partial class AppShell : Xamarin.Forms.Shell
{
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(NoweFiszki), typeof(NoweFiszki));            
    }

}

It is everything what I wrote.

CodePudding user response:

A couple of things have to be corrected on your code:

In NoweFiszkiViewModel you are creating a new instance of ListViewFlascardViewModel every time, and adding elements on that new instance, which does not affect the instance to which ListViewFlashcard is actually bound.

To fix this, you will have to create a public static ListViewFlascardViewModel in ListViewFlashcard.xaml.cs and set the binding context to it, as follows

ListViewFlashcard.xaml.cs

public static ListViewFlascardViewModel vm { get; set; }

public ListViewFlashcard()
{
    InitializeComponent();
    vm = new ListViewFlascardViewModel();
}

protected override void OnAppearing()
{
    base.OnAppearing();
            
    BindingContext = vm;
}

then correct ListViewFlashcard.xaml as follows

ListViewFlashcard.xaml

<!--<ContentPage.BindingContext>
        <viewmodels:ListViewFlascardViewModel/>
    </ContentPage.BindingContext>-->
<StackLayout>
    <Button 
        Command="{Binding GoToAddFlashcard}"
        Text="Click Me"/>

    <ListView ItemsSource="{Binding Fiszka}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="viewmodels:Flashcard">
                <TextCell Text="{Binding Name}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>

Finally you have to correct NoweFiszkiViewModel.cs as follows, adding the new elements to the public static view model:

NoweFiszkiViewModel.cs

public Command SaveFlashcard { get; }

public NoweFiszkiViewModel()
{
    SaveFlashcard = new Command(save);
}

//ListViewFlascardViewModel list = new ListViewFlascardViewModel();

private async void save()
{
    ListViewFlashcard.vm.Fiszka.Add(new Flashcard { Name = "Bye" });
    await Shell.Current.GoToAsync("..");
}
  • Related