我有一个文本框,当用户按下回车键时,我们会执行API调用。但是在此期间我想更新XAML布局以显示进度条。但是,布局更新仅在方法完成后进行,这意味着在我们进行搜索时没有可见的进度条。
我们已经覆盖了OnKeyDown事件来处理用户按Enter键。
有没有办法在此方法期间强制执行XAML布局更新?
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter && (xaml_search_box.FocusState == Windows.UI.Xaml.FocusState.Pointer || xaml_search_box.FocusState == Windows.UI.Xaml.FocusState.Keyboard))
{
//We want to make the progressbar visible here
xaml_search_progressbar.Visibility = Windows.UI.Xaml.Visibility.Visible
//collapse keyboard
Windows.UI.ViewManagement.InputPane.GetForCurrentView().TryHide();
string _query = xaml_search_box.Text;
List<Task> tasks = new List<Task>();
//Long web request
Task t = Task.Run(() => APICall.BasicSearch(_query));
tasks.Add(t);
Task.WaitAll(tasks.ToArray());
m_results = APICall.m_basicsearch;
xaml_search_results.ItemsSource = m_results;
xaml_search_results_grid.ItemsSource = m_results;
}
base.OnKeyDown(e);
//Our layout is updated here, AFTER we have done the search making it pointless to show a loading bar
}
答案 0 :(得分:3)
您需要控制UI线程,以便有机会显示进度指示器。一种方便的方法是使用async / await关键字:
protected override async void OnKeyDown(KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter && (xaml_search_box.FocusState == Windows.UI.Xaml.FocusState.Pointer || xaml_search_box.FocusState == Windows.UI.Xaml.FocusState.Keyboard))
{
//We want to make the progressbar visible here
xaml_search_progressbar.Visibility = Windows.UI.Xaml.Visibility.Visible
//collapse keyboard
Windows.UI.ViewManagement.InputPane.GetForCurrentView().TryHide();
// Yield control to the UI thread
await Task.Delay(10);
string _query = xaml_search_box.Text;
List<Task> tasks = new List<Task>();
//Long web request
Task t = Task.Run(() => APICall.BasicSearch(_query));
tasks.Add(t);
Task.WaitAll(tasks.ToArray());
m_results = APICall.m_basicsearch;
xaml_search_results.ItemsSource = m_results;
xaml_search_results_grid.ItemsSource = m_results;
}
base.OnKeyDown(e);
//Our layout is updated here, AFTER we have done the search making it pointless to show a loading bar
}
也就是说,在等待任务时你不应该阻止UI线程。您应该使用WhenAll
代替WaitAll
:
await Task.WhenAll(tasks.ToArray());
答案 1 :(得分:0)
您不需要列表。只需等待Task.Run()调用即可。 await将返回UI线程并启用进度条。非常简单。您还需要使事件处理程序异步。
await Task.Run(() => APICall.BasicSearch(_query));
答案 2 :(得分:0)
您需要将重写的方法与protected override async void OnKeyDown(KeyRoutedEventArgs e)
异步,否则它将阻止UI线程。如果可能的话,您还应该考虑将APICall.BasicSearch方法更改为异步方法,因此您不需要分离这样的任务,而只需执行m_results = await APICall.BasicSearch(_query);