windows phone开发学习--ProgressOverlay等待提醒

来源:互联网 发布:动漫人物的发型知乎 编辑:程序博客网 时间:2024/06/06 02:28

在windows phone开发中,难免要遇到与服务器交互或者本地进行数据处理的时候,在这个时候系统要有很好的提示功能,告诉用户现在不要以为系统死机了,就好比安装软件的时候progressbar能告诉我们进度,那个小绿条能让我们安心。在手机上,我们应该也要实现这样的功能,这样才能算是友好的界面设计。

首先给出实现效果,如下图所示:

可以看到,当前界面是由两块组成的,一个是后台背景,一个前台的progressoverlay。在这里我的后台其实就是一个简单的textblock,当progressoverlay出现的时候自动让后台变灰,隐藏于后端,可以说这是一个非常好的界面设计。如果就在textblock上面叠加,界面将会是这样:

你说你还能看清progress提示的是什么么?

更多例子请从这里下载: http://www.windowsphonegeek.com/upload/articles/ProgressOverlayDemo.zip

下面就说说实现:

1、首先下载coding4fun这个类库,http://coding4fun.codeplex.com/ 这绝对是大大的好东西

2、添加dll到工程中,在前一篇中已经讲过了,截图如下:

3、与toastpromote不同的是,这里我们不是在页面后台.cs文件中调用,而是直接放在前台xaml文件之中

在xaml中添加命名空间

xmlns:Controls="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"


然后使用控件即可

       <Controls:ProgressOverlay Name="progressOverlay" >                <Controls:ProgressOverlay.Content>                    <TextBlock>国庆节千万不要来北京玩啊,人挤死人</TextBlock>                </Controls:ProgressOverlay.Content>            </Controls:ProgressOverlay>


有一点需要注意,这个添加的控件代码的位置应该放在其他控件的后面,这样才能实现把前一个控件进行后台隐藏化的效果,例如和刚才的textblock搭配就是这样:

    <Grid x:Name="LayoutRoot" Background="Transparent">        <TextBlock Height="691" HorizontalAlignment="Left" Margin="33,45,0,0" Name="text" Text="我是中国人,钓鱼岛是中国的              " VerticalAlignment="Top" Width="447" />        <Controls:ProgressOverlay Name="progressOverlay" >                <Controls:ProgressOverlay.Content>                    <TextBlock>国庆节千万不要来北京玩啊,人挤死人</TextBlock>                </Controls:ProgressOverlay.Content>            </Controls:ProgressOverlay>       </Grid>


于是上面的第一个效果就这样实现了。

当然,我敢保证很多人按照我的这个方法并没有实现这样的效果,我看了代码示例后也觉得很困惑,为什么我和代码示例一模一样,可偏偏实现不了呢?在coding4fun讨论区我也看到一群外国人在讨论这个ProgressOverlay无法显示问题。最终,我发现了原来代码示例用的是老的dll,而现在更新的dll实现方式变了,通过查询,我找到解决方法,新浪博客上面居然也有技术文章,让我狂汗:http://blog.sina.com.cn/s/blog_94000f5201012t56.html

解决方法就是:

一:还是添加引用和命名空间

xmlns:slToolkit ="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"xmlns:c4f="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"xmlns:Converters="clr-namespace:Coding4Fun.Phone.Controls.Converters;assembly=Coding4Fun.Phone.Controls"


二:这样写控件代码:

c4f:ProgressOverlay Name="progressOverlay" Visibility="{Binding OverlayVis}"><c4f:ProgressOverlay.Resources><Converters:VisibilityToBooleanConverter x:Key="VisToBoolConverter" /></c4f:ProgressOverlay.Resources><StackPanel><TextBlock HorizontalAlignment="Center">Loading</TextBlock><slToolkit:PerformanceProgressBar IsIndeterminate="{Binding ElementName=progressOverlay, Path=Visibility, Converter={StaticResource VisToBoolConverter}}"/></StackPanel></c4f:ProgressOverlay>


我想这样改正以后就能真正实现效果了。

当然,也许还有一些人会疑惑这样没什么用,毕竟这是页面中写死的,根本不像按钮点击那样进行相应,而经过事件触发产生这样的效果才是可用的。于是,我觉得我应该这样做:

1、创建一个用户控件页面,在该用户控件页面中使用这个progressoverlay控件

xmal代码如下:

<UserControl x:Class="UserControls.ProgressControl"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     xmlns:slToolkit ="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"     xmlns:c4f="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"     xmlns:Converters="clr-namespace:Coding4Fun.Phone.Controls.Converters;assembly=Coding4Fun.Phone.Controls"    mc:Ignorable="d"    FontFamily="{StaticResource PhoneFontFamilyNormal}"    FontSize="{StaticResource PhoneFontSizeNormal}"    Foreground="{StaticResource PhoneForegroundBrush}"    d:DesignHeight="768" d:DesignWidth="480">    <Grid x:Name="LayoutRoot" Background="Transparent" Width="480" Height="800" >        <c4f:ProgressOverlay Name="progressOverlay" Visibility="{Binding OverlayVis}">            <c4f:ProgressOverlay.Resources>                <Converters:VisibilityToBooleanConverter x:Key="VisToBoolConverter" />            </c4f:ProgressOverlay.Resources>            <StackPanel>                <TextBlock HorizontalAlignment="Center" Name="textBlockStatus">Loading</TextBlock>                <slToolkit:PerformanceProgressBar IsIndeterminate="{Binding ElementName=progressOverlay, Path=Visibility, Converter={StaticResource VisToBoolConverter}}"/>            </StackPanel>        </c4f:ProgressOverlay>    </Grid></UserControl>


后台.cs代码如下:

using System;using System.Windows;using System.Windows.Controls;using System.Windows.Controls.Primitives;namespace UserControls{public partial class ProgressControl : UserControl{public ProgressControl(){InitializeComponent();}internal Popup ChildWindowPopup { get; private set; }public void SetMessage(string message){textBlockStatus.Text = message;}public void Show(){if (this.ChildWindowPopup == null){this.ChildWindowPopup = new Popup();try{this.ChildWindowPopup.Child = this;}catch (ArgumentException){throw new InvalidOperationException("The control is already shown.");}}if (this.ChildWindowPopup != null && Application.Current.RootVisual != null){this.ChildWindowPopup.IsOpen = true;}}public void Hide(){// Restore system traythis.ChildWindowPopup.IsOpen = false;}}}


2、在需要调用该控件的事件函数中使用该控件,例如我在同步的时候调用该控件,添加引用然后创建该对象即可

    //执行同步的响应函数public class SyncHandler{ProgressControl progressDialog;        //ProgressIndicator progressDialog;DoEndEventHandler doEndHandler;public SyncHandler(DoEndEventHandler doEnd){doEndHandler = doEnd;}public void HandleMessage(object sender, SyncEventArgs e){            //异步调用显示输出Deployment.Current.Dispatcher.BeginInvoke(() =>{if (progressDialog == null){                        progressDialog = new ProgressControl();}progressDialog.Show();if (e.MsgID == SyncService.BEGIN_SYNC_MSG){progressDialog.SetMessage("开始同步");}else if (e.MsgID == SyncService.BEGIN_GOOGLE_SYNC){progressDialog.SetMessage("开始同步Google日历");}else if (e.MsgID == SyncService.BEGIN_365_SYNC){progressDialog.SetMessage("开始同步");}else if (e.MsgID == SyncService.SYNC_GOOGLE_ERROR){                        var toast = new ToastPrompt                        {                            Message = "同步Google日历出错",                        };                        toast.Show();}else if (e.MsgID == SyncService.END_SYNC_MSG){progressDialog.Hide();                        var toast = new ToastPrompt                        {                            Message = "同步完成",                        };                        toast.Show();doEndHandler();}else if (e.MsgID == SyncService.START_REC_MSG){progressDialog.SetMessage("正在处理第" + e.Number + "条");}else if (e.MsgID == SyncService.END_REC_MSG){progressDialog.SetMessage("数据处理完毕");}else if (e.MsgID == SyncService.SYNC_SEND_NUM){progressDialog.SetMessage("正在发送第" + e.Number + "条");}else if (e.MsgID == SyncService.SYNC_REC_NUM){progressDialog.SetMessage("正在接收第" + e.Number + "条");}else if (e.MsgID == SyncService.SYNC_NO_NETWORK){                        var toast = new ToastPrompt                        {                            Message = "无法访问网络,请检查网络连接",                        };                        toast.Show();}else if (e.MsgID == SyncService.SYNC_NO_CRED){                        var toast = new ToastPrompt                        {                            Message = "账号认证失败,请检查365账号设置",                        };                        toast.Show();}else if (e.MsgID == SyncService.START_CALENDAR_SYNC){progressDialog.SetMessage("开始同步日历");}else if (e.MsgID == SyncService.START_SCHEDULE_SYNC){progressDialog.SetMessage("开始同步日程");}else if (e.MsgID == SyncService.START_NOTE_SYNC){progressDialog.SetMessage("开始同步待办");}else if (e.MsgID == SyncService.GOOGLE_TOKEN_ERROR){                        var toast = new ToastPrompt                        {                            Message = "Google认证失败",                        };                        toast.Show();AccountEntity account = AccountControl.GetAccount();account.GoogleAccountState = AccountEntity.GOOGLE_USER_TOKEN_INVALIDATE;AccountControl.SaveAccount(account);}else if (e.MsgID == SyncService.SHOW_SLOW_SYNC){                        var toast = new ToastPrompt                        {                            Message = "正在同步全部数据",                        };                        toast.Show();//MessageBox.Show("正在同步全部数据");}else if (e.MsgID == SyncService.SYNC_RUNNING){                        var toast = new ToastPrompt                        {                            Message = "后台运行同步",                        };                        toast.Show();//MessageBox.Show("后台运行同步");}else{progressDialog.SetMessage("出错了,亲");}});}}


这下就大功告成了,而且完全能保证progressoverlay能出现在任何页面之前把后台页面进行隐藏化。同时,你还可以在progressoverlay结束时调用toastpromote,实现更好的用户交互性。

原创粉丝点击