'ObservableCollection count resets to 0 from second function call in Xamarin forms app
There is a Dependency class in android that has these two functions
1. public void OnEvent(Java.Lang.Object obj, FirebaseFirestoreException error)
{
try
{
var docs = (QuerySnapshot)obj;
visitorDetails.Clear();
foreach (var doc in docs.Documents)
{
Console.WriteLine(doc.Get("VisitorName").ToString());
var visitordetails = new VisitorDetails
{
Name = doc.Get("VisitorName").ToString(),
ContactNumber = doc.Get("VisitorContact").ToString(),
VehicleNumber = doc.Get("VisitorVehicleNo").ToString(),
IsApproved = doc.Get("VisitorIsApproved").ToString(),
IsActive = doc.Get("VisitorIsActive").ToString(),
Purpose = doc.Get("PurposeOfVisit").ToString(),
Email = doc.Get("VisitorEmail").ToString(),
FromDate = toDatetime(doc.GetDate("FromDate") as Date),
ToDate = toDatetime(doc.GetDate("ToDate") as Date),
docID = doc.Id
};
visitorDetails.Add(visitordetails);
}
Console.WriteLine("onevent - " + visitorDetails.Count.ToString());
HasReadCompleted = true;
MessagingCenter.Send<object, string>(this, "HasChanges", "true");
}
catch (FirebaseFirestoreException error1)
{
Console.WriteLine(readMode + error1.Message);
HasReadCompleted = false;
}
}
2. public async Task<ObservableCollection<VisitorDetails>> ReadVisitorDetails()
{
try
{
Console.WriteLine("return - " + visitorDetails.Count.ToString());
return visitorDetails;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return null;
}
}
In my PCL ViewModel class
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using ULTIMATE_VMS.Models;
using ULTIMATE_VMS.ViewModels.Helpers;
using ULTIMATE_VMS.Views;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace ULTIMATE_VMS.ViewModels
{
public class VMSPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private static IFirestore firestore;
#region properties
private string fullname;
public string FullName
{
get
{
return fullname;
}
set
{
fullname = value;
OnPropertyChanged("FullName");
OnPropertyChanged("CanApprove");
}
}
private string phonenumber;
public string Phone_Number
{
get
{
return phonenumber;
}
set
{
phonenumber = value;
OnPropertyChanged("Phone_Number");
OnPropertyChanged("CanApprove");
}
}
private string emailid;
public string Email_ID
{
get
{
return emailid;
}
set
{
emailid = value;
OnPropertyChanged("Email_ID");
OnPropertyChanged("CanApprove");
OnPropertyChanged("CanSearch");
}
}
private string companyname;
public string Company_Name
{
get
{
return companyname;
}
set
{
companyname = value;
OnPropertyChanged("Company_Name");
OnPropertyChanged("CanApprove");
}
}
private string vehiclenumber;
public string Vehicle_Number
{
get
{
return vehiclenumber;
}
set
{
vehiclenumber = value;
OnPropertyChanged("Vehicle_Number");
OnPropertyChanged("CanApprove");
}
}
private DateTime fromdate;
public DateTime From_Date
{
get
{
return fromdate;
}
set
{
fromdate = value;
OnPropertyChanged("FromDate");
OnPropertyChanged("CanApproveExecute");
}
}
private DateTime todate;
public DateTime To_Date
{
get
{
return todate;
}
set
{
todate = value;
OnPropertyChanged("ToDate");
OnPropertyChanged("CanApproveExecute");
}
}
private string purpose;
public string Vis_Purpose
{
get { return purpose; }
set { purpose = value; }
}
private ObservableCollection<VisitorDetails> visitordets;
public ObservableCollection<VisitorDetails> visitordetails
{
get
{
return visitordets;
}
set
{
visitordets = value;
OnPropertyChanged("visitordetails");
}
}
private ObservableCollection<VisitorDetails> upcomingvisitors;
public ObservableCollection<VisitorDetails> upcomingVisitors
{
get
{
return upcomingvisitors;
}
set
{
upcomingvisitors = value;
OnPropertyChanged("visitordetails");
}
}
private ObservableCollection<VisitorDetails> apprdetails;
public ObservableCollection<VisitorDetails> approvedetails
{
get
{
return apprdetails;
}
set
{
apprdetails = value;
OnPropertyChanged("approvedetails");
}
}
private IList<VisitorDetails> details;
public IList<VisitorDetails> Details {
get {
return details;
}
set
{
details = value;
}
}
private bool hasapproval;
public bool HasApprovals
{
get { return hasapproval; }
set { hasapproval = value; }
}
private bool hasupcoming;
public bool HasUpcoming
{
get { return hasupcoming; }
set { hasupcoming = value; }
}
private bool hasnoupcoming;
public bool HasNoUpcoming
{
get { return hasnoupcoming; }
set { hasnoupcoming = value; }
}
private bool isrefreshing;
public bool IsRefreshing
{
get { return isrefreshing; }
set { isrefreshing = value; }
}
private VisitorDetails selectedItem;
public VisitorDetails SelectedItem
{
get { return selectedItem; }
set { selectedItem = value; }
}
private bool haslogs;
public bool HasLogs
{
get { return haslogs; }
set { haslogs = value; }
}
private bool hasnologs;
public bool HasNoLogs
{
get { return hasnologs; }
set { hasnologs = value; }
}
private string condoname;
public string Condo_Name
{
get
{
return condoname;
}
set
{
condoname = value;
OnPropertyChanged("Condo_Name");
OnPropertyChanged("CanApply");
OnPropertyChanged("CanSearch");
}
}
private string blockno;
public string Block_No
{
get
{
return blockno;
}
set
{
blockno = value;
OnPropertyChanged("Block_No");
OnPropertyChanged("CanApply");
OnPropertyChanged("CanSearch");
}
}
private string unitno;
public string Unit_No
{
get
{
return unitno;
}
set
{
unitno = value;
OnPropertyChanged("Unit_No");
OnPropertyChanged("CanApply");
OnPropertyChanged("CanSearch");
}
}
private int tabindex;
public int TabIndex
{
get { return tabindex; }
set { tabindex = value; }
}
#endregion
public ICommand Accept { protected set; get; }
public ICommand Decline { protected set; get; }
public ICommand CallVisitor { protected set; get; }
public ICommand RefreshPage { protected set; get; }
public ICommand ItemTappedCommand { get; private set; }
public ICommand ApproveCommand { protected set; get; }
public ICommand SearchCommand { protected set; get; }
public ICommand clearfields { protected set; get; }
private UserDetails userdetails;
public VMSPageViewModel()
{
firestore = DependencyService.Get<IFirestore>();
tabindex = 0;
OnPropertyChanged("TabIndex");
Accept = new Command<VisitorDetails>(OnAcceptClick);
Decline = new Command<VisitorDetails>(OnDeclineClick);
CallVisitor = new Command<VisitorDetails>(OnCallClick);
RefreshPage = new Command(OnrefClick);
ItemTappedCommand = new Command(ItemTapped);
clearfields = new Command(clearFields);
ApproveCommand = new Command(OnApproveClick, CanApproveExecute);
SearchCommand = new Command(OnSearchClick, CanSearchExecute);
visitordetails = new ObservableCollection<VisitorDetails>();
approvedetails = new ObservableCollection<VisitorDetails>();
upcomingVisitors = new ObservableCollection<VisitorDetails>();
Details = new ObservableCollection<VisitorDetails>();
userdetails = new UserDetails();
hasapproval = false;
hasupcoming = false;
hasnoupcoming = !hasupcoming;
haslogs = false;
hasnologs = !haslogs;
OnPropertyChanged("HasUpcoming");
OnPropertyChanged("HasNoUpcoming");
OnPropertyChanged("HasApprovals");
OnPropertyChanged("HasLogs");
OnPropertyChanged("HasNoLogs");
From_Date = DateTime.Now;
To_Date = DateTime.Now;
CheckForChanges();
getuserDetails();
firestore.InitListners();
//ProcessData();
}
public void CheckForChanges()
{
MessagingCenter.Subscribe<object, string>
(this, "HasChanges", (sender, status) =>
{
if(status=="true" && userdetails != null)
{
ProcessData();
}
});
}
public async void getuserDetails()
{
userdetails = null;
userdetails = await firestore.ReadUserDetails();
}
public async void OnApproveClick(Object parameter)
{
UserDetails userdetails = await firestore.ReadUserDetails();
await firestore.AddVisitorDetails(new VisitorDetails
{
Name = FullName,
Email = Email_ID,
ResEmail = userdetails.Email,
CondoName = userdetails.CondoName,
BlockNo = userdetails.BlockNumber,
UnitNo = userdetails.UnitNo,
ContactNumber = Phone_Number,
CompanyName = Company_Name,
VehicleNumber = Vehicle_Number,
Purpose = Vis_Purpose,
FromDate = From_Date,
ToDate = To_Date,
IsActive = "True",
IsApproved = "True",
CreationDate = DateTime.Now
});
Console.WriteLine("Visitor Added");
await Shell.Current.DisplayAlert("Successfull", "Visitor Addedd Successfully", "Ok");
clearFields();
tabindex = 0;
OnPropertyChanged("TabIndex");
ProcessData();
}
public async void OnSearchClick(Object parameter)
{
ResidentDetails resdetails = await firestore.ReadUserDetails("Email", Email_ID);
if (resdetails != null)
{
FullName = resdetails.Name;
Phone_Number = resdetails.ContactNumber;
Company_Name = resdetails.CompanyName;
Vehicle_Number = resdetails.VehicleNumber;
Condo_Name = resdetails.CondoName;
Block_No = resdetails.BlockNumber;
Unit_No = resdetails.UnitNo;
}
}
public void clearFields()
{
FullName = "";
Email_ID = "";
Phone_Number = "";
Company_Name = "";
Vehicle_Number = "";
Vis_Purpose = "";
Condo_Name = "";
Block_No = "";
Unit_No = "";
From_Date = DateTime.Now;
To_Date = DateTime.Now;
}
private bool CanApproveExecute(object arg)
{
return CanApprove;
}
public bool CanApprove
{
get
{
return !string.IsNullOrEmpty(FullName) && !string.IsNullOrEmpty(Phone_Number) && !string.IsNullOrEmpty(Email_ID) && !string.IsNullOrEmpty(Vehicle_Number) && !string.IsNullOrEmpty(Vis_Purpose);
}
}
private bool CanSearchExecute(object arg)
{
return CanSearch;
}
public bool CanSearch
{
get
{
return !string.IsNullOrEmpty(Email_ID);
}
}
public void OnrefClick()
{
ProcessData();
isrefreshing = false;
OnPropertyChanged("IsRefreshing");
}
private void OnPropertyChanged(string PropertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
public async void ProcessData()
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(1000);
if (userdetails != null)
{
//Console.WriteLine("Writew success");
break;
}
}
hasupcoming = false;
OnPropertyChanged("HasUpcoming");
hasnoupcoming = !hasupcoming;
OnPropertyChanged("HasNoUpcoming");
try
{
details.Clear();
details = firestore.ReadVisitorDetails();
OnPropertyChanged("Details");
visitordets.Clear();
upcomingvisitors.Clear();
apprdetails.Clear();
if (details != null && userdetails != null)
{
foreach (var visitor in details)
{
if (!visitor.Email.Equals(userdetails.Email))
{
visitor.FDate = visitor.FromDate.ToString("dd/MM/yyyy");
visitor.TDate = visitor.ToDate.ToString("dd/MM/yyyy");
visitordets.Add(visitor);
if (visitor.IsApproved.Equals("False") && visitor.FromDate.Date >= DateTime.Now.Date) //Pending approval visitors
{
apprdetails.Add(visitor);
hasapproval = true;
OnPropertyChanged("HasApprovals");
}
if (visitor.IsApproved.Equals("True") && visitor.FromDate.Date >= DateTime.Now.Date)
{
upcomingvisitors.Add(visitor);
hasupcoming = true;
OnPropertyChanged("HasUpcoming");
hasnoupcoming = !hasupcoming;
OnPropertyChanged("HasNoUpcoming");
}
}
}
}
if (visitordets.Count <= 0)
{
haslogs = false;
hasnologs = !haslogs;
}
else
{
haslogs = true;
hasnologs = !haslogs;
}
OnPropertyChanged("HasLogs");
OnPropertyChanged("HasNoLogs");
OnPropertyChanged("visitordetails");
OnPropertyChanged("approvedetails");
OnPropertyChanged("upcomingVisitors");
}
catch (Exception ex)
{
Console.WriteLine("Master" + ex.Message);
}
}
public async void OnAcceptClick(VisitorDetails details)
{
Console.WriteLine("AcceptClick " + details.docID);
apprdetails.Remove(details);
OnPropertyChanged("approvedetails");
if (apprdetails.Count <= 0)
{
hasapproval = false;
OnPropertyChanged("HasApprovals");
}
await firestore.UpdateField(details.docID, "visitorDetails", "VisitorIsApproved", "True");
}
public async void OnDeclineClick(VisitorDetails details)
{
Console.WriteLine("DeclineClick " + details.docID);
apprdetails.Remove(details);
OnPropertyChanged("approvedetails");
if (apprdetails.Count <= 0)
{
hasapproval = false;
OnPropertyChanged("HasApprovals");
}
await firestore.DeleteDoc(details.docID, "visitorDetails");
}
public void OnCallClick(VisitorDetails details)
{
try
{
PhoneDialer.Open(details.ContactNumber);
}
catch (ArgumentNullException ex)
{
Console.WriteLine(ex.Message);
}
catch (FeatureNotSupportedException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public async void ItemTapped()
{
var visitordetails = new VisitorDetails()
{
Name = SelectedItem.Name,
Email = SelectedItem.Email,
ContactNumber = SelectedItem.ContactNumber,
VehicleNumber = SelectedItem.VehicleNumber,
IsApproved = SelectedItem.IsApproved,
IsActive = SelectedItem.IsActive,
Purpose = SelectedItem.Purpose,
FromDate = SelectedItem.FromDate,
ToDate = SelectedItem.ToDate,
};
await Shell.Current.Navigation.PushAsync(new LogDetailsPage(visitordetails));
/* await Shell.Current.GoToAsync($"//LogDetailsPage?Name={SelectedItem.Name}&" +
$"ContactNumber={SelectedItem.ContactNumber}&" +
$"VehicleNumber={SelectedItem.VehicleNumber}&" +
$"IsApproved={SelectedItem.IsApproved}&" +
$"IsActive={SelectedItem.IsActive}&" +
$"Purpose={SelectedItem.Purpose}&" +
$"Email={SelectedItem.Email}&" +
$"FromDate={SelectedItem.FromDate}&" +
$"ToDate={SelectedItem.ToDate}");*/
}
}
}
so my PCL class calls ReadVisitorDetails() whenever the MessagingCenter text is true
The first time when it runs the output is fine onevent - 1 return - 1
after the first time return is always 0 onevent - 1 return - 0
visitorDetails is a class variable initialized inside the constructor
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|