C# 如何结合异步调用对进度条进行编程?

C# 如何结合异步调用对进度条进行编程?,c#,xaml,asynchronous,windows-phone-8,progress-bar,C#,Xaml,Asynchronous,Windows Phone 8,Progress Bar,首先,我对Windows Phone 8开发的经验不是很丰富,但有些东西看起来像是我比较熟悉的ASP.NET框架。 我想要一个不确定的进度条,它在后台执行web请求时显示,在处理请求时隐藏 我的解决方案可行,但我对它不满意(progressBar/Text位于一个pivot元素中,用于测试功能) 我们有以下几点: 一个名为“MainPage”的XAML页面,其中包含Pivot元素 <phone:PhoneApplicationPage> ... <Grid x:Na

首先,我对Windows Phone 8开发的经验不是很丰富,但有些东西看起来像是我比较熟悉的ASP.NET框架。

我想要一个不确定的进度条,它在后台执行web请求时显示,在处理请求时隐藏

我的解决方案可行,但我对它不满意
(progressBar/Text位于一个pivot元素中,用于测试功能)
我们有以下几点:

一个名为“MainPage”的XAML页面,其中包含Pivot元素

<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>
函数LoadSomething()显示/隐藏进度条和加载文本。
这是我不满意的部分:

// 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;
        });
}
现在我的问题是:

  • 是否可以在我导航到的任何透视元素上显示进度条和加载文本

  • 如您所见,通过引用“(主页)App.RootFrame.Content”我可以访问我的进度条/文本对象并简单地设置属性。但我不喜欢这样
    我认为一定有一种方法可以使用{Binding…}值设置进度条/文本,从而使代码更干净。 因此,如何绑定ProgressBar和ProgressText的属性“可见性”,使它们在LoadSomething()开始时变为“可见”,并在处理完成时变为“折叠”

  • 提前谢谢


    好心的问候

    你几乎已经解决了,至少你描述了第二点的解决方案

  • 这很简单,只需将TextBlock和ProgressBar放在xaml的Pivot下,这样它们就可以呈现Pivot元素的顶部。然后可以使用水平对齐、垂直对齐和边距对其进行排列。下面的代码应该把它们放在页面的中间:

    <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>
    
    (NotifyPropertyChanged是您的版本:

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(String name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(name));
    }
    
  • 如果您还没有BooleanToVisibilityConverter,请添加此类以将布尔值转换为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;
        }
    }
    
    在主页创建过程中,您可以将整个页面的DataContext或TextBlock和ProgressBar设置为您的ViewModel(或者通过Resources和xaml进行设置,但这并不重要),添加BooleanToVisibilityConverter作为页面资源,如下所示:

    protected override void OnNavigatedTo(
        App.ViewModel.LoadSomething();
    }
    
    <phone:PhoneApplicationPage.Resources>
         <local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </phone:PhoneApplicationpage.Resources>
    
    
    
    并将TextBlock和ProgressBar的可见性属性绑定到ViewModel的IsLoading属性:

    private bool _IsLoading = false;
    
    public bool IsLoading
    {
        get { return _IsLoading; }
        set
        {
            if (_IsLoading != value)
            {
                _IsLoading = value;
                NotifyPropertyChanged("IsLoading");
            }
        }
    }
    
    <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"/>
    
    
    
    最后一件事是:


    在LoadSomething()的开头,您设置了
    IsLoading=true;
    ,在HandleResponse方法的结尾,设置了
    IsLoading=false;
    ,这样就可以了。

    谢谢您,这完全让它起作用了:)我有关于IValueConverter的章节,但我忘记了如何将它与INotifyPropertyChanged对象的属性结合使用。