如何结合异步调用对进度条进行编程
本文关键字:编程 调用 异步 何结合 结合 | 更新日期: 2023-09-27 18:19:39
首先,我对Windows Phone 8开发的经验不是很大,但有些东西看起来像 ASP.NET 我更熟悉的框架。
我想要一个不确定的进度条,在后台执行 Web 请求时显示,并在处理请求时隐藏。
我的解决方案有效,但我对它
不满意(进度条/文本在一个枢轴元素内以测试功能(
我们有以下几点:
名为"主页"的 XAML 页面,其中包含透视元素。
<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>
我的代码隐藏如下所示:
protected override void OnNavigatedTo(
App.ViewModel.LoadSomething();
}
函数 LoadSomething(( 显示/隐藏进度条和 load-text.
这是我不满意的部分:
// 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;
});
}
所以现在我的问题:
是否可以在我导航到的任何透视元素上显示进度条和加载文本?
如您所见,通过引用"(MainPage(App.RootFrame.Content",我可以访问我的进度条/文本对象并简单地设置属性。但我不喜欢这种方式。
我认为一定有一种方法可以使用{绑定...}值设置进度条/文本,从而使代码更简洁。因此,我如何绑定进度条和进度文本的属性"可见性",以便它们在 LoadSomething(( 开始时变为"可见",并在处理完成后变为"折叠"?
提前感谢!
亲切问候
好吧,您几乎已经解决了它,至少您描述了第二点的解决方案。
-
这很简单,只需将文本块和进度条放在 xaml 中的透视下,以便它们呈现在透视元素的顶部。然后,您可以使用水平对齐、垂直对齐和边距排列它们。下面的代码应该将它们放在页面的中间:
<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>
-
几乎一样简单。我怀疑您的 ViewModel 实现了 INotifyPropertyChanged 还是从某个类派生而来?如果没有,那就这样做。将此属性添加到视图模型:
private bool _IsLoading = false; public bool IsLoading { get { return _IsLoading; } set { if (_IsLoading != value) { _IsLoading = value; NotifyPropertyChanged("IsLoading"); } } }
(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 设置为您的 ViewModel(或者通过资源和 xaml 执行此操作,但这并不重要(,将 BooleanToVisibilityConverter 添加为页面资源,如下所示:
<phone:PhoneApplicationPage.Resources>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</phone:PhoneApplicationpage.Resources>
并将 TextBlock 和进度条的可见性属性绑定到视图模型的 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;
,这应该可以做到。