首先,我对Windows Phone 8开发的经验不是很大,但有些东西看起来像我更熟悉的ASP.NET Framework。
我想要一个不确定的进度条,它在后台执行Web请求时显示,并在处理请求时隐藏。
我的解决方案有效但我对它不满意(并且progressBar / Text位于一个枢轴元素内以测试功能)
我们有以下内容:
带有数据透视表元素的名为“MainPage”的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();
}
Function 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;
});
}
现在我的问题是:
是否可以在我导航到的任何枢轴元素上显示进度条和加载文本?
如您所见,通过引用“(MainPage)App.RootFrame.Content”,我可以访问Progress-Bar / Text对象并简单地设置属性。但我不喜欢这样。
我认为必须有一种方法可以使用{Binding ...}值设置Progress-Bar / Text,这样可以使代码更清晰。
因此,如何绑定ProgressBar和ProgressText的属性“Visibility”,以便它们在LoadSomething()开始时变为“可见”,并在处理完成时变为“折叠”?
提前致谢!
亲切的问候
答案 0 :(得分:3)
嗯,你几乎已经解决了,至少你描述了第二点的解决方案。
这个非常简单,只需将TextBlock和ProgressBar放在xaml的Pivot下,这样它们就可以渲染出pivot元素。然后,您可以使用HorizontalAlignment,VerticalAlignment和Margin来排列它们。下面的代码应该将它们放在页面的中间位置:
<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或派生自某些类吗?如果没有,那就不行了。 然后将此属性添加到ViewModel:
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;
}
}
在MainPage创建中,您可以将整个页面的DataContext或TextBlock和ProgressBar设置为ViewModel(或者通过Resources和xaml进行,但这无关紧要),将BooleanToVisibilityConverter添加为Page像这样的资源:
<phone:PhoneApplicationPage.Resources>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</phone:PhoneApplicationpage.Resources>
并将TextBlock和ProgressBar的Visibility属性绑定到ViewModel的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;
的末尾设置,并且应该这样做。