How to program my progress bar in combination with asynchronous calls?

First of all, my experience in developing Windows Phone 8 is not very large, but some things look like the ASP.NET Framework, which I am more familiar with.

I want an undefined progress bar that appears when a web request is running in the background and that hides when processing the request.

My solution works, but I'm not happy with it
(and progressBar / Text were inside the same pivot element to test functionality)
We have the following:

XAML page called "MainPage" with Pivot elements.

<phone:PhoneApplicationPage> ... <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!-- HERE I want the progress bar and loading-text to show up if possible --> <TextBlock Name="ProgressText" Text="Loading..." Visibility="Collapsed"/> <ProgressBar Name="ProgressBar" Visibility="Collapsed" IsIndeterminate="True"/> <!-- HERE I want the progress bar and loading-text to show up if possible --> <phone:Pivot Title="MyTitle"> <!-- Here are my PivotItems --> </phone:Pivot> </Grid> <phone:PhoneApplicationPage> 

My codebehind looks like this:

 protected override void OnNavigatedTo( App.ViewModel.LoadSomething(); } 

The LoadSomething () function shows / hides the progress bar and loading text.
This is the part that doesn't suit me:

 // Method of the ViewModel public void LoadSomething() { //Showing progress bar and loading-text var mainPage = (MainPage)App.RootFrame.Content; mainPage.ProgressBar.Visibility = Visibility.Visible; mainPage.ProgressText.Visibility = Visibility.Visible; // form the URI UriBuilder fullUri = new UriBuilder(string.Format("http://somepage...")); // initialize a new WebRequest HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fullUri.Uri); // set up the state object for the async request UpdateState state = new UpdateState(); state.AsyncRequest = request; // start the asynchronous request request.BeginGetResponse( new AsyncCallback(HandleResponse), state); } private void HandleResponse(IAsyncResult asyncResult) { // Here happens logic and stuff Deployment.Current.Dispatcher.BeginInvoke(() => { // Here happens logic and stuff //Hiding progress bar and loading-text var mainPage = (MainPage)App.RootFrame.Content; mainPage.ProgressBar.Visibility = Visibility.Collapsed; mainPage.ProgressText.Visibility = Visibility.Collapsed; }); } 

So now my questions are:

  • Is it possible to display a progress bar and load text into any rotation element that I switched to?

  • As you can see, on the link ((MainPage) App.RootFrame.Content "I can get to the Progress-Bar / Text objects and just set the attributes. But I do not like it.
    I thought there should be a way to set Progress-Bar / Text with the value {Binding ...}, which makes the code cleaner. Thus, how can I bind the Visibility attribute to the ProgressBar and ProgressText so that they become β€œvisible” when LoadSomething () is run and that they will complete the β€œcrash” when processing is completed?

Thanks in advance!

Yours faithfully

+4
source share
1 answer

Well, you have almost solved this, at least you have described the solution for the second point.

  • It's very simple, just put the TextBlock and ProgressBar under your Pivot in your xaml so that they display the ontop of the pivot element. You can then arrange them using the HorizontalAlignment, VerticalAlignment, and Margin functions. The code below should put them in the middle of your page:

     <phone:PhoneApplicationPage> ... <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <phone:Pivot Title="MyTitle"> <!-- Here are my PivotItems --> </phone:Pivot> <!-- HERE I want the progress bar and loading-text to show up if possible --> <TextBlock Name="ProgressText" Text="Loading..." Visibility="Collapsed" VerticalAlignment="Center" HorizontalAlignment="Stretch"/> <ProgressBar Name="ProgressBar" Visibility="Collapsed" IsIndeterminate="True" VerticalAlignment="Center" HorizontalAlignment="Stretch"/> <!-- HERE I want the progress bar and loading-text to show up if possible --> </Grid> <phone:PhoneApplicationPage> 
  • Almost as easy. I suspect your ViewModel implements INotifyPropertyChanged or comes from some class that does this? If not, how to do it. Then add this property to your ViewModel:

     private bool _IsLoading = false; public bool IsLoading { get { return _IsLoading; } set { if (_IsLoading != value) { _IsLoading = value; NotifyPropertyChanged("IsLoading"); } } } 

    (With NotifyPropertyChanged your version will be:

     public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(String name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(name)); } 

If you don't already have a BooleanToVisibilityConverter, add this class to convert the boolean value to visible in xaml:

 public class BooleanToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value is Visibility && (Visibility)value == Visibility.Visible; } } 

In your MainPage creation, you set the DataContext of the entire page or just the TextBlock and ProgressBar as your ViewModel (or you do it through resources and xaml, but it does not matter), add a BooleanToVisibilityConverter as a page resource similar to this:

 <phone:PhoneApplicationPage.Resources> <local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> </phone:PhoneApplicationpage.Resources> 

and bind the visibility properties of TextBlock and ProgressBar to the IsLoading property of your ViewModel:

 <TextBlock Name="ProgressText" Text="Loading..." Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/> <ProgressBar Name="ProgressBar" Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}" IsIndeterminate="True" VerticalAlignment="Center" HorizontalAlignment="Stretch"/> 

The last thing to do:

At the beginning of LoadSomething () you set IsLoading = true; and at the end of the HandleResponse method IsLoading = false; and that should do it.

+3
source

Source: https://habr.com/ru/post/1487734/


All Articles