如何在 xamarin 表单中使用异步更改 ui
how to change change ui with async in xamarin forms
我尝试以 xamarin 形式开发移动应用程序。
我有新闻列表,我正在使用 SQLite 来存储它。
当我的主页打开时,在我从 SQLite 获取新闻之前,我尝试从 Web API 获取新新闻。我可以在 SQLite 中保存新消息,但我的 UI 没有改变。我该如何解决?
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{}
}
该代码适用于将新新闻保存到 SQLite,但我无法将新闻异步绑定到 UI。
编辑:
杰森回答后,这是我的代码最新版本
Device.BeginInvokeOnMainThread 解决我的问题。
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 需要使用 BeginInvokeOnMainThread
在 UI 线程上进行更改
Device.BeginInvokeOnMainThread( () =>
{
MaiNewsList.ItemsSource = newsList.Where(x => x.Type.Equals((int)NewsType.MainNews)).OrderBy(x => x.Sort).ToList();
});
我尝试以 xamarin 形式开发移动应用程序。 我有新闻列表,我正在使用 SQLite 来存储它。 当我的主页打开时,在我从 SQLite 获取新闻之前,我尝试从 Web API 获取新新闻。我可以在 SQLite 中保存新消息,但我的 UI 没有改变。我该如何解决?
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{}
}
该代码适用于将新新闻保存到 SQLite,但我无法将新闻异步绑定到 UI。
编辑:
杰森回答后,这是我的代码最新版本 Device.BeginInvokeOnMainThread 解决我的问题。
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 需要使用 BeginInvokeOnMainThread
Device.BeginInvokeOnMainThread( () =>
{
MaiNewsList.ItemsSource = newsList.Where(x => x.Type.Equals((int)NewsType.MainNews)).OrderBy(x => x.Sort).ToList();
});