WinPhone 8.1 |强制xaml布局更改

时间:2015-06-09 15:28:47

标签: c# xaml windows-phone-8.1 win-universal-app

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

3 个答案:

答案 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);

行的操作。