I have xamarin forms app which have a picker at the top and a listview just beneath it.When the app launches the data on picker will bind from a web API.Then after according to the picker value another API call will be done and the listview will load. When the user changes the value of picker, then Listview should be updated.I am not using any viewmodel.I have a helper class for API call and I am setting the json result to a list and Set it as itemsource for my listview. Somehow I achieved it but it is not smooth and sometimes gets Error as "Outof memmory exception" when I change the value of picker.NB: I am using a custom picker with Rg.popup.Plugin. Which will set the selected value to a label.
My questions are
- Is this the proper way to load a listview which will update when changing the value of picker? What corrections should I do?
- Should I use a viewmodel(MVVM) pattern for this scenerio? My list will contains much larger data.
My xamal.cs NB: The APICall class will return the json in proper format.
public partial class List : ContentPage
{
string weekstart;
string WeekString;
ObservableCollection<PickerData> resultObjcallForPicker = new ObservableCollection<PickerData>();
public TimeSheetList()
{
InitializeComponent();
Thread loadScreenItemsThread = new Thread(new ThreadStart(LoadScreenItemsAsync));
loadScreenItemsThread.Start();
}
public async void LoadScreenItemsAsync()
{
//Picker Data loading
string postdataForPicker = "{\"Username\":\"" + Settings.userID + "\",\"ConnectionString\":\"" + Settings.String+ "\"}";
APICall callForPicker = new APICall("/API/ListMobile/PickerData", postdataForPicker, loadingIndicator);
try
{
resultObjcallForPicker = callForPicker.APICallResult<ObservableCollection<PickerData>>();
if (resultObjcallForPicker != null)
{
WeekString = DateTime.Parse(resultObjcallForPicker[0].SDate).ToString("dd-MMM-yyyy");
Device.BeginInvokeOnMainThread(async () =>
{
// Setting the value of picker initially.
WeekStart.Text = WeekString;
});
await loadList();
}
else
{
Device.BeginInvokeOnMainThread(async () =>
{
UserDialogs.Instance.HideLoading();
await DisplayAlert("", "error occured", "OK");
});
}
}
catch (Exception)
{
Device.BeginInvokeOnMainThread(async () =>
{
UserDialogs.Instance.HideLoading();
ErrorMessageData errorMessage = new ErrorMessageData();
errorMessage.Flag = false; errorMessage.Message = callForPicker.errorMessage.Message;
});
}
}
//<<----------------Loading Listview----------------------->>
public async Task loadList()
{
string postdataForList = "{\"date\":\"" + WeekStart.Text + "\"}";
APICall callForList = new APICall("/API/ListMobile/ListForApproval", postdataForList, loadingIndicator);
try
{
List<ListData> resultObjForListst = callForList.APICallResult<List<ListData>>();
if (resultObjForListst != null)
{
List.ItemsSource = resultObjForListst;
screenStackLayout.VerticalOptions = LayoutOptions.FillAndExpand;
List.IsVisible = true;
}
else
{
Device.BeginInvokeOnMainThread(async () =>
{
await DisplayAlert("", "Please check network connection", "OK");
});
}
}
catch (Exception)
{
Device.BeginInvokeOnMainThread(async () =>
{
ErrorMessageData errorMessage = new ErrorMessageData();
errorMessage.Flag = false; errorMessage.Message = callForList.errorMessage.Message;
});
}
}
void Picker_tapped(object sender,EventArgs e)
{
PopupNavigation.PushAsync(new WeekStartPopUp(WeekStartList));
MessagingCenter.Subscribe<MyMessage>(this, "WeekStartData", (value) =>
{
string receivedData = value.Myvalue;
WeekStart.Text = receivedData;
Device.BeginInvokeOnMainThread(async () =>
{
try {
loadList();
}
catch(Exception Ex)
{
}
});
});
}
}
Any help is appreciated.Please tell me if any additional information is needed.