The “Selected” status of a selection from a ListView is lost between operations and I need to reinstate it

Grime 786 Reputation points
2021-08-11T04:14:43.623+00:00

I select an "Operator" from a ListView then use Xamarin.Essentials Preferences to store the various Operator attributes, as per SelectOperatorPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using HandsFreeNotes.ViewModel;
using HandsFreeNotes.Model;
using HandsFreeNotes.Data;

using Xamarin.Essentials;

namespace HandsFreeNotes.View
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class SelectOperatorPage : ContentPage
    {
        OperatorViewModel ovm;

        public EventHandler<OperatorModel> ReturnValue;

        public SelectOperatorPage()
        {
            // add a bit of padding to cater to the "notch" on the iPhone.
            if (Device.RuntimePlatform == Device.iOS) { Padding = new Thickness(0, 40, 0, 0); }

            InitializeComponent();

        }

        protected override async void OnAppearing()
        {
            base.OnAppearing();

            HFNDatabase database = await HFNDatabase.Instance;
            OperatorListView.ItemsSource = await database.GetOperatorsAsync();

        }

        private async void BackButton_Clicked(object sender, EventArgs e)
        {
            await Navigation.PopModalAsync();
        }

        private async void OperatorListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            if (e.SelectedItem != null)
            {

                OperatorModel operatorModel = (OperatorModel)e.SelectedItem;

                EventHandler<OperatorModel> handler = ReturnValue;
                if (handler != null)
                {
                    handler(this, operatorModel);

                    // Added these lines to set Xamarin.Essentials Preferences keys GMB: 07/06/2021
                    Preferences.Clear();
                    int selOpID = operatorModel.OperatorID;
                    string selOpName = operatorModel.OperatorName;
                    string selOpPhone = operatorModel.OperatorPhone;
                    string selOpEmail = operatorModel.OperatorEmail;
                    string selOpAvatar = operatorModel.OperatorAvatar;
                    Preferences.Set("selOpID_key", selOpID.ToString());
                    Preferences.Set("selOpName_key", selOpName);
                    Preferences.Set("selOpPhone_key", selOpPhone);
                    Preferences.Set("selOpEmail_key", selOpEmail);
                    Preferences.Set("selOpAvatar_key", selOpAvatar);

                    // DisplayAlert("Alert", selOpID.ToString() + " - " + selOpName + " - " + selOpPhone + " - " + selOpEmail + " - " + selOpAvatar, "Continue");
                }

                await Navigation.PopModalAsync();
            }
        }
    }
}

When the app is later opened again, I reinstate the Operator Name ("selOpName") to a button name, but when I click on "Update Operator", the Operator is no longer selected. This happens in OperatorsPage.xaml.cs:

using HandsFreeNotes.ViewModel;
using HandsFreeNotes.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using HandsFreeNotes.Data;

namespace HandsFreeNotes.View
{
    [XamlCompilation(XamlCompilationOptions.Compile)]

    public partial class OperatorsPage : ContentPage
    {
        OperatorViewModel ovm;
        OperatorModel opm;

        public EventHandler<OperatorModel> ReturnValue;

        public OperatorsPage(OperatorModel SelectModel)

        {
            // add a bit of padding to cater to the "notch" on the iPhone.
            if (Device.RuntimePlatform == Device.iOS) { Padding = new Thickness(0, 40, 0, 0); }

            InitializeComponent();

            if (SelectModel != null)
            {
                opm = SelectModel;
            }
            else
            {
                opm = new OperatorModel();
            }

            BindingContext = opm;
        }

        private async void BackButton_Clicked(object sender, EventArgs e)
        {
            if (SelectModel != null)
            {
                EventHandler<OperatorModel> handler = ReturnValue;
                if (handler !=null)
                {
                    handler(this, opm);
                }
            }

            await Navigation.PopModalAsync();
        }

        private async void AddOperatorButton_Clicked(object sender, EventArgs e)
        {
            await Navigation.PushModalAsync(new NewOperatorPage { 
              BindingContext = new OperatorModel()
            });

        }

        private async void SelectOperatorButton_Clicked(object sender, EventArgs e)
        {
            SelectOperatorPage page = new SelectOperatorPage();
            page.ReturnValue += delegate (object s, OperatorModel operatorModel)
            {
                BackCall(s, operatorModel);
            };

            await Navigation.PushModalAsync(page);
        }
        OperatorModel SelectModel;


        private void BackCall(object s, OperatorModel model)
        {
            SelectModel = model;
            opm.OperatorName = model.OperatorName;
        }

        private async void DeleteOperatorButton_Clicked(object sender, EventArgs e)
        {
            if (SelectModel != null)
            {
                bool answer = await DisplayAlert("Warning!", "Do you really want to delete Operator " + SelectModel.OperatorName, "Yes", "No");

                if (answer == true)
                {
                    HFNDatabase database = await HFNDatabase.Instance;
                    await database.DeleteItemAsync(SelectModel);
                    SelectModel = null;
                    SelectedOperatorEntry.Text = "";
                }
            }
            else
            {
                await DisplayAlert("Info", "Please select an Operator to delete", "OK");
            }
        }
        private async void UpdateOperatorButton_Clicked(object sender, EventArgs e)
        {

            if (SelectModel != null)
            {
                var operatorInfoPage = new OperatorInfoPage(SelectModel);
                operatorInfoPage.ReturnValue += delegate (object s, OperatorModel operatorModel)
                {
                    BackCall(s, operatorModel);
                };
                await Navigation.PushModalAsync(operatorInfoPage);
            }

            else
            {
                await DisplayAlert("Info", "Please select an Operator", "OK");
            }
        }
    }
}

In the last method (UpdateOperatorButton_Clicked), I suspect I have to add an "else if" statement to rebuild the selection from my saved Preferences, potentially calling the BackCall method, but I'm floundering on how to do that.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,302 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Grime 786 Reputation points
    2021-08-14T04:08:47.56+00:00

    Thanks for responding @Kyle Wang .
    The calling XAML files are here:
    SelectOperatorPage.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"  
                 x:Class="HandsFreeNotes.View.SelectOperatorPage">  
      
        <ContentPage.Content>  
            <Grid BackgroundColor="White">  
                <Grid.RowDefinitions>  
                    <RowDefinition Height="40"/>  
                    <RowDefinition Height="40"/>  
                    <RowDefinition Height="80"/>  
                    <RowDefinition Height="*"/>  
                    <RowDefinition Height="50"/>  
                </Grid.RowDefinitions>  
      
                <Grid.ColumnDefinitions>  
                    <ColumnDefinition Width="50"/>  
                    <ColumnDefinition Width="*"/>  
                    <ColumnDefinition Width="50"/>  
                </Grid.ColumnDefinitions>  
      
                <Button  
                    x:Name="BackButton"  
                    Text="Back"  
                    Grid.Row="0"  
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    TextColor="Black"  
                    FontAttributes="Bold"  
                    HeightRequest="40"  
                    VerticalOptions="CenterAndExpand"  
                    HorizontalOptions="End"  
                    Margin="0,0,20,0"  
                    Clicked="BackButton_Clicked"/>  
      
                <Image   
                    Source="hfn256"  
                    Margin="2"  
                    Grid.Row="1"   
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    HorizontalOptions="Center"  
                    BackgroundColor="Transparent"/>  
      
                <Label   
                    Text="Select Operator..."  
                    FontSize="Large"  
                    TextColor="Black"  
                    FontAttributes="Bold"  
                    Grid.Row="2"   
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    HorizontalOptions="Center"  
                    VerticalOptions="Start"  
                    Margin="20"  
                    BackgroundColor="Transparent"/>  
      
                <ListView  
                    x:Name="OperatorListView"  
                    Grid.Row="3"  
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    RowHeight="140"  
                    ItemSelected="OperatorListView_ItemSelected">  
                    <ListView.ItemTemplate>  
                        <DataTemplate>  
                            <ViewCell>  
                                <ContentView>  
                                    <Grid>  
                                        <Grid.RowDefinitions>  
                                            <RowDefinition Height="*"/>  
                                        </Grid.RowDefinitions>  
                                        <Grid.ColumnDefinitions>  
                                            <ColumnDefinition Width="100"/>  
                                            <ColumnDefinition Width="100"/>  
                                            <ColumnDefinition Width="200"/>  
                                        </Grid.ColumnDefinitions>  
      
                                        <Image  
                                            Source="{Binding OperatorAvatar}"  
                                            Grid.Row="0"  
                                            Grid.Column="0"  
                                            HeightRequest="200"  
                                            WidthRequest="100"/>  
      
                                        <Label  
                                            Text="{Binding OperatorName}"  
                                            FontAttributes="Bold"  
                                            HorizontalOptions="Start"  
                                            VerticalOptions="Center"  
                                            Grid.Row ="0"  
                                            Grid.Column="1"/>  
      
                                        <Label  
                                            Text="{Binding OperatorEmail}"  
                                            FontAttributes="Italic"  
                                            FontSize="Micro"  
                                            Grid.Row="0"  
                                            Grid.Column="2"  
                                            HeightRequest="30"  
                                            HorizontalOptions="Start"  
                                            VerticalOptions="Center"/>  
      
                                        <Label  
                                            Text="{Binding OperatorPhone}"  
                                            FontAttributes="Italic"  
                                            FontSize="Small"  
                                            Grid.Row="0"  
                                            Grid.Column="2"  
                                            HeightRequest="30"  
                                            HorizontalOptions="Start"  
                                            VerticalOptions="End"/>  
      
                                    </Grid>  
                                </ContentView>  
                            </ViewCell>  
                        </DataTemplate>  
                    </ListView.ItemTemplate>  
                </ListView>  
            </Grid>  
        </ContentPage.Content>  
    </ContentPage>  
    

    OperatorsPage.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"  
                 x:Class="HandsFreeNotes.View.OperatorsPage">  
        <ContentPage.Content>  
            <Grid BackgroundColor="White">  
                <Grid.RowDefinitions>  
                    <RowDefinition Height="40"/>  
                    <RowDefinition Height="40"/>  
                    <RowDefinition Height="40"/>  
                    <RowDefinition Height="70"/>  
                    <RowDefinition Height="*"/>  
                    <RowDefinition Height="50"/>  
                </Grid.RowDefinitions>  
      
                <Grid.ColumnDefinitions>  
                    <ColumnDefinition Width="50"/>  
                    <ColumnDefinition Width="*"/>  
                    <ColumnDefinition Width="50"/>  
                </Grid.ColumnDefinitions>  
      
                <Button  
                    x:Name="BackButton"  
                    Text="Back"  
                    Grid.Row="0"  
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    TextColor="Black"  
                    FontAttributes="Bold"  
                    HeightRequest="40"  
                    VerticalOptions="Center"  
                    HorizontalOptions="End"  
                    Margin="0,0,20,0"  
                    Clicked="BackButton_Clicked"/>  
      
                <Image   
                    Source="hfn256"  
                    Margin="2"  
                    Grid.Row="1"   
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    HorizontalOptions="Center"  
                    BackgroundColor="Transparent"/>  
      
                <Label   
                    Text="Operator"  
                    FontSize="Large"  
                    TextColor="Black"  
                    FontAttributes="Bold"  
                    Margin =" 0, 0, 0, 0"  
                    Grid.Row="2"   
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    HorizontalOptions="Center"  
                    VerticalOptions="End"  
                    BackgroundColor="Transparent"/>  
      
                <StackLayout  
                    Grid.Row="3"   
                    Grid.Column="0"  
                    Grid.ColumnSpan="3"  
                    Orientation="Horizontal">  
      
                    <Label  
                        Text="Selected&#x0a;Operator: "  
                        TextColor="Black"  
                        FontSize="Medium"  
                        FontAttributes="Bold"  
                        HorizontalOptions="End"  
                        VerticalOptions="Center"  
                        BackgroundColor="Transparent"  
                        Margin="40, 0, 0, 0"  
                        WidthRequest="250"/>  
      
                    <Entry   
                        x:Name="SelectedOperatorEntry"  
                        Text="{Binding OperatorName}"  
                        TextColor="Green"  
                        IsReadOnly="True"  
                        Placeholder="No Currently Selected Operator"  
                        PlaceholderColor="LightGray"  
                        FontSize="Medium"  
                        FontAttributes="Italic"  
                        Margin ="0, 0, 0, 0"  
                        HorizontalOptions="Center"  
                        VerticalOptions="Center"  
                        BackgroundColor="Transparent"  
                        WidthRequest="280"/>  
      
                </StackLayout>  
      
                <ScrollView   
                    Orientation="Vertical"  
                    Grid.Row="4"   
                    Grid.Column="0"  
                    Grid.ColumnSpan="3">  
                    <Grid BackgroundColor="White" >  
                        <Grid.RowDefinitions>  
                            <RowDefinition Height="50"/>  
                            <RowDefinition Height="50"/>  
                            <RowDefinition Height="50"/>  
                            <RowDefinition Height="100"/>  
                            <RowDefinition Height="20"/>  
                        </Grid.RowDefinitions>  
      
                        <Grid.ColumnDefinitions>  
                            <ColumnDefinition Width="50"/>  
                            <ColumnDefinition Width="*"/>  
                            <ColumnDefinition Width="50"/>  
                        </Grid.ColumnDefinitions>  
      
                        <Button  
                            x:Name="SelectOperatorButton"  
                            Text="Select Operator"  
                            FontSize="Medium"  
                            Grid.Row="0"  
                            Grid.Column="1"  
                            TextColor="Black"  
                            FontAttributes="Bold"  
                            BackgroundColor="White"  
                            Margin="0,0,0,0"  
                            HorizontalOptions="Center"  
                            VerticalOptions="Start"  
                            Clicked="SelectOperatorButton_Clicked"/>  
      
                        <Button  
                            x:Name="UpdateOperatorButton"  
                            Text="Update Selected Operator"  
                            FontSize="Medium"  
                            Grid.Row="1"  
                            Grid.Column="1"  
                            TextColor="Black"  
                            FontAttributes="Bold"  
                            BackgroundColor="White"  
                            Margin="0,0,0,0"  
                            HorizontalOptions="Center"  
                            VerticalOptions="Start"  
                            Clicked="UpdateOperatorButton_Clicked"/>  
      
                        <Button  
                            x:Name="DeleteOperatorButton"  
                            Text="Delete Selected Operator"  
                            FontSize="Medium"  
                            Grid.Row="2"  
                            Grid.Column="1"  
                            TextColor="Black"  
                            FontAttributes="Bold"  
                            BackgroundColor="White"  
                            Margin="0,0,0,0"  
                            HorizontalOptions="Center"  
                            VerticalOptions="Start"  
                            Clicked="DeleteOperatorButton_Clicked"/>  
      
                        <Button  
                            x:Name="AddOperatorButton"  
                            Text="Add New Operator"  
                            FontSize="Medium"  
                            Grid.Row="3"  
                            Grid.Column="1"  
                            HorizontalOptions="Center"  
                            VerticalOptions="End"  
                            TextColor="Black"  
                            FontAttributes="Bold"  
                            BackgroundColor="White"  
                            Margin="0,0,0,0"  
                            Clicked="AddOperatorButton_Clicked"/>  
      
                    </Grid>  
      
                </ScrollView>  
      
            </Grid>  
        </ContentPage.Content>  
    </ContentPage>  
    
    0 comments No comments

  2. Kyle Wang 5,531 Reputation points
    2021-08-16T02:31:33.067+00:00

    Hi Grime,

    Welcome to our Microsoft Q&A platform!

    So you want to access the previously selected item even after reopening the app, then you just need to read the data through Preferences in the constructor of the OperatorsPage and instantiate the SelectModel.

    The following example also contains code to pass the SelectModel from the SelectOperatorPage to the OperatorsPage.

    SelectOperatorPage.xaml.cs

    public partial class SelectOperatorPage : ContentPage  
    {  
        public List<OperatorModel> Operators { get; private set; }  
      
        public event TransfDelegate TransfEvent;  
      
        public SelectOperatorPage()  
        {  
            InitializeComponent();  
      
            // set itemsource  
            Operators = new List<OperatorModel>();  
            for (int i = 0; i < 10; i++)  
            {  
                Operators.Add(new OperatorModel { OperatorID = $"ID{i}", OperatorName = $"Name{i}" });  
            }  
      
            this.BindingContext = this;  
        }  
      
        private void OperatorListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)  
        {  
            OperatorModel selectedItem = e.SelectedItem as OperatorModel;  
      
            TransfEvent(selectedItem);  
      
            Preferences.Set("OperatorID", selectedItem.OperatorID);  
            Preferences.Set("OperatorName", selectedItem.OperatorName);  
        }  
    }  
      
    public delegate void TransfDelegate(OperatorModel operatorModel);  
    

    OperatorsPage.xaml.cs

    public OperatorsPage()  
    {  
        InitializeComponent();  
      
        SelectModel = new OperatorModel  
        {  
            OperatorID = Preferences.Get("OperatorID", "default_value"),  
            OperatorName = Preferences.Get("OperatorName", "default_value")  
        };  
    }  
      
    private async void SelectOperatorButton_Clicked(object sender, EventArgs e)  
    {  
        SelectOperatorPage page = new SelectOperatorPage();  
      
        page.TransfEvent += Page_TransfEvent;  
      
        await Navigation.PushModalAsync(page);  
    }  
      
    OperatorModel SelectModel;  
      
    private void Page_TransfEvent(OperatorModel operatorModel)  
    {  
        SelectModel = operatorModel;  
    }  
      
    private void UpdateOperatorButton_Clicked(object sender, EventArgs e)  
    {  
        Console.WriteLine("SelectModel.OperatorID + "\n" + SelectModel.OperatorName + "\n");  
    }  
    

    Regards,
    Kyle


    If the response is helpful, please click "Accept Answer" and upvote it.

    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.