WinPhone 8.1 |强制xaml布局改变

本文关键字:xaml 布局 改变 强制 WinPhone | 更新日期: 2023-09-27 17:54:59

我有一个文本框,当用户按下enter键时,我们执行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
    }

WinPhone 8.1 |强制xaml布局改变

您需要将控制权交给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());

您不需要List。只需等待Task.Run()调用。await将返回UI线程,并显示进度条。非常简单。您还需要将事件处理程序设置为异步。

await Task.Run(() => APICall.BasicSearch(_query));

你需要使被覆盖的方法与protected override async void OnKeyDown(KeyRoutedEventArgs e)异步,否则它会阻塞UI线程。您还应该考虑更改APICall。如果可能的话,将BasicSearch方法转换为异步方法,因此您不需要像这样剥离Tasks,而是可以按照m_results = await APICall.BasicSearch(_query);

这样做。