I try to develop a mobile app in xamarin forms. I have news list and i am using SQLite for store that. When my main page open, before i get the news from SQLite and then i try to get new news from web API. I can save the new news in SQLite but my UI hasn't changed. How can i fix that?
public MainPage()
{
InitializeComponent();
database = new Helper.xxxDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "xxx.db3"));
SetLocalDBMainNews();
Task.Run(async () => { await GetNewsAsync(); });
}
void SetLocalDBMainNews()
{
if(database.TableExists("News"))
{
List<News> newsList = database.GetNewsData();
if (newsList.Count > 0)
{
MaiNewsList.ItemsSource = newsList.Where(x => x.Type.Equals((int)NewsType.MainNews)).OrderBy(x => x.Sort).ToList();
}
}
else
database.CreateNewsTable();
}
private async Task GetNewsAsync()
{
try
{
var register = database.GetRegisterData();
string url = "http://xxx.azurewebsites.net/api/News/GetPublishedNews";
var response = Tools.Send(url, "GET", register.Token);
var result = JsonConvert.DeserializeObject<ApiResponse<List<News>>>(response);
if (result.HasError == false)
{
var newsList = result.Value;
database.DeleteAllNews();
foreach(var n in newsList)
{
database.Insert(n);
}
MaiNewsList.ItemsSource = newsList.Where(x => x.Type.Equals((int)NewsType.MainNews)).OrderBy(x => x.Sort).ToList();
}
}
catch{}
}
The code works for saving new news to SQLite but i couldn't bind the news to UI in async.
Edit :
After jason's answer, here is the my code latest version Device.BeginInvokeOnMainThread solve the my problem.
private async Task GetNewsAsync()
{
try
{
var register = database.GetRegisterData();
string url = "http://xxx.azurewebsites.net/api/News/GetPublishedNews";
var response = Tools.Send(url, "GET", register.Token);
var result = JsonConvert.DeserializeObject<ApiResponse<List<News>>>(response);
if (result.HasError == false)
{
var newsList = result.Value;
database.DeleteAllNews();
foreach(var n in newsList)
{
database.Insert(n);
}
Device.BeginInvokeOnMainThread(() =>
{
MaiNewsList.ItemsSource = newsList.Where(x => x.Type.Equals((int)NewsType.MainNews)).OrderBy(x => x.Sort).ToList();
});
}
}
catch
{
}
}
UI changes need to happen on the UI thread using BeginInvokeOnMainThread
Device.BeginInvokeOnMainThread( () =>
{
MaiNewsList.ItemsSource = newsList.Where(x => x.Type.Equals((int)NewsType.MainNews)).OrderBy(x => x.Sort).ToList();
});