ProgressRing is not showing while the app runs

2019-09-05 04:53发布

I am developing a 'Universal App' for Windows 8.1 and Windows Phone 8.1

I need to add a ProgressRing control to my page, because there is a task which takes some time to complete and I should notify the user that the app is loading data. So I followed the instruction on MDSN in the following link:

To create an indeterminate progress ring and they stated what I exactly need:

4. Adding an indeterminate progress ring

When you can't estimate how much work remains to finish a task and the task does block user interaction, use an indeterminate progress ring. An indeterminate progress ring shows an animate sequence of dots moving in a circle.

The problem is that the ProgressRing doesn't play the animation of "loading", when I insert prog.IsActive = true; before the code that starts the task

If I comment the Task lines of code, it plays.

XAML :

 <ProgressRing x:Name="prog" Margin="435,349,388,181" FontFamily="{StaticResource FontFamily6}" FontSize="25" />

C#:

 private void LevelTap(object sender, TappedRoutedEventArgs e)
    {
        prog.IsActive = true;
        CheckNav(sender);
    }

private void CheckNav(object sender)
    {
        TextBlock tb = sender as TextBlock;
        GameSetter game = new GameSetter();
        game.Level = (int)TextDict[tb];
        if (!LevelsArr[game.Level]) return;
        if (!goToLeader)
        {            
            prog.IsActive = false;
            CallNav(true, game);
        }
        else
        {
            prog.IsActive = false;
            CallNav(false, game);
        }    
    }

    private void CallNav(bool b,GameSetter g)
    { 
        if(b)  Frame.Navigate(typeof(Game8), g);
        else Frame.Navigate(typeof(MainPage), g);
    }

Note: The Task that runs uses Dictionary, Windows.Storage.ApplicationData, and Navigation for another page in the end.

2条回答
ゆ 、 Hurt°
2楼-- · 2019-09-05 05:33

You can use this code block in every function too if Progressing inDeterminate mode always open:

  #region Progress Ring Start
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                Waiter.Visibility = Visibility.Visible; // Progress ring name is Waiter.
            });

            #endregion
            await Task.Delay(1000);
            CheckNav(sender); // Your process



            #region Progress Ring Finish
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                Waiter.Visibility = Visibility.Collapsed; // Progress ring name is Waiter.

            });
            #endregion
查看更多
Luminary・发光体
3楼-- · 2019-09-05 05:51

The flaw in your code (except the fact that it's probably nearly instant anyway, as notes @kennyzx), is that you need the LevelTap method to return for the UI to be updated. And when the method returns, you've already set the ProgressRing.IsActive property back to false, which means nothing is displayed at all.

One simple way to fix that is to use the async Task.Yield method to give the UI thread a chance to run:

private async void LevelTap(object sender, TappedRoutedEventArgs e)
{
    prog.IsActive = true;

    await Task.Yield();

    CheckNav(sender);
}

But almost nothing will be shown since your code shouldn't take long to execute. If you really want to force the indicator to be displayed for 0.5 seconds, you can do something like:

private async void LevelTap(object sender, TappedRoutedEventArgs e)
{
    prog.IsActive = true;

    await Task.Delay(500);

    CheckNav(sender);
}
查看更多
登录 后发表回答