博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

03,构建WP8应用程序

Posted on 2012-12-09 10:00  淡如水wp  阅读(3295)  评论(3编辑  收藏  举报

内容预告:

  • Application Bar
  • 页面导航
  • 处理页面的横竖向改变
  • 处理不同的屏幕分辨率
  • 本地化
  • Toolkit
  • 页面过渡

Frame 和 Page:

Frame是最外层的窗器,是PhoneApplicationFrame类,包括Page和系统元素(像系统托盘,ApplicationBar)。
Page填充整个Frame的内容区域,从PhoneApplicationPage类派生,包括一个Title,可选择是否加入ApplicationBar。

页面导航:Silverlight在WindowsPhone上用基于页面的导航模式,类似Web页面导航,每个页面有一个URI,每个页面本质上是无状态的。

private void HyperlinkButton_Click_1(                  object sender, RoutedEventArgs e)
 {
   NavigationService.Navigate(    new Uri("/SecondPage.xaml", UriKind.Relative));
 }

导航--后退:程序提供了向前导航的接口:

private void HyperlinkButton_Click_1(  object sender, RoutedEventArgs e)
 {
   NavigationService.Navigate(    new Uri("/SecondPage.xaml", UriKind.Relative));
 }

物理后退键也会引起后退到前页,而不用写任何代码

重写后退按键的事件:也许需要在用户按了后退键时做一些程序上的判断,比如弹出一个提示窗问用户是否真的想后退,因为可能是误操作。

<phone:PhoneApplicationPage
    x:Class="PhoneApp1.MainPage"
    …
    shell:SystemTray.IsVisible="True"
    BackKeyPress="PhoneApplicationPage_BackKeyPress">


In code:
 private void PhoneApplicationPage_BackKeyPress(object sender,System.ComponentModel.CancelEventArgs e)
 {
     e.Cancel = true;    // Tell system we've handled it

     // Hide the popup...
     ...
 }

在页面间传数据:

1,在页面间传字符串:

private void passParam_Click(object sender, RoutedEventArgs e) {    
NavigationService.Navigate(new Uri("/SecondPage.xaml?msg=" + textBox1.Text, UriKind.Relative));
}

在目标页面接收:

 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
 {
     base.OnNavigatedTo(e);

     string querystringvalue = "";
    if (NavigationContext.QueryString.TryGetValue("msg", out querystringvalue))
        textBlock1.Text = querystringvalue;
 }

 

  2,在页面间传递对象:

    • 一种方式是将对象存在App类里(也就是全局对象)
    • 另一种还是用导航函数传:
// Navigate to the new page
 NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + 
(MainLongListSelector.SelectedItem as ItemViewModel).ID, UriKind.Relative));

处理非线性导航:要细心设计程序的导航策略。
如果从“第三页”跳转到“首页”,然后再点击物理后退按钮,会发生什么?
用户想退出程序,可是程序却回到了“第三页”。其实可以用NavigationService.RemoveBackEntry()来清除后退栈。

当“第三页”跳转到“首页”,在导航的参数中加一个传递参数:

NavigationService.Navigate(new Uri("/MainPage.xaml?homeFromThird=true", UriKind.Relative));

在“首页”的OnNavigatedTo事件中,检测是否有这个传递参数,如果有的话,移除"第三页"和"第二页"的导航栈位置。

 protected override void OnNavigatedTo(NavigationEventArgs e) 
{     
if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New && 
NavigationContext.QueryString.ContainsKey("homeFromThird")) { NavigationService.RemoveBackEntry(); // Remove ThirdPage NavigationService.RemoveBackEntry(); // Remove SecondPage
NavigationService.RemoveBackEntry();
// Remove original MainPage } base.OnNavigatedTo(e); }

 


 

系统托盘和Application Bar:系统托盘包括一些系统自带的指示符显示系统状态(如信号,声音,日期),可以通过Microsoft.Phone.Shell.SystemTray.IsVisible = false; 显示或隐藏。Application Bar可以显示一些按钮或常用的菜单。

 Application Bar:

  • 用Application Bar替代一些自定义右键菜单。
  • 最多4个按钮。除非必须,别放满4个。
  • 上滑Application Bar带出更多菜单。
  • 图标应该用白色的前景色放在透明的背景上。

在XAML中设置Application Bar:

<phone:PhoneApplicationPage 
    x:Class="CRMapp.MainPage“
   …>   <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar x:Name="AppBar" Opacity="1.0" IsMenuEnabled="True">
            <shell:ApplicationBar.Buttons>
                <shell:ApplicationBarIconButton x:Name="NewContactButton" IconUri="Images/appbar.new.rest.png"                                                 Text="New" Click="NewContactButton_Click"/>
                <shell:ApplicationBarIconButton x:Name="SearchButton" IconUri="Images/appbar.feature.search.rest.png"                                                 Text="Find" Click="SearchButton_Click"/>
            </shell:ApplicationBar.Buttons>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem x:Name="GenerateMenuItem" Text="Generate Data"                                               Click="GenerateMenuItem_Click" />
                <shell:ApplicationBarMenuItem x:Name="ClearMenuItem" Text="Clear Data"                                               Click="ClearMenuItem_Click" />
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>        
    </phone:PhoneApplicationPage.ApplicationBar>

</phone:PhoneApplicationPage>

Application Bar屏幕横竖向:横向时Application Bar在侧边,系统自带动画处理过渡。

Application Bar的透明度:如果透明度小于1,页面大小会撑满屏幕,Application Bar会覆盖页面,如果透明度等于1,页面大小会撑到Application Bar,Application Bar则不会覆盖页面。

在Blend中设计Application Bar:


手机的横竖向:不是所有的应用需要横向,可以通过配置让应用支持横向或倒向:

在Visual Studio 2012中设计横向UI:

选择方向

SupportedOrientations="Portrait"

SupportedOrientations="PortraitOrLandscape"

相应的布局也许需要调整:

用Grid做横向布局:第二列是在竖向时没有用到的

<phone:PivotItem Header="recipe">
   <Grid>
     <Grid.ColumnDefinitions>
       <ColumnDefinition Width="*"/>
       <ColumnDefinition Width="Auto"/>
     </Grid.ColumnDefinitions>
     <Grid.RowDefinitions>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="240"/>
       <RowDefinition Height="*"/>
       <RowDefinition Height="Auto"/>
     </Grid.RowDefinitions>
...
   </Grid>

横向时:将菜谱的描述移动到第二行第二列,现在第三行没有用到了。因为行高是*,其自动收缩为0.

<phone:PivotItem Header="recipe">
   <Grid>
     <Grid.ColumnDefinitions>
       <ColumnDefinition Width="*"/>
       <ColumnDefinition Width="Auto"/>
     </Grid.ColumnDefinitions>
     <Grid.RowDefinitions>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="240"/>
       <RowDefinition Height="*"/>
       <RowDefinition Height="Auto"/>
     </Grid.RowDefinitions>
...
   </Grid>

移动元素:

private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)        
{    
if (this.Orientation == PageOrientation.LandscapeLeft || this.Orientation ==                                                                  PageOrientation.LandscapeRight)    
{         
DirectionsScrollViewer.SetValue(Grid.RowProperty, 1);         
DirectionsScrollViewer.SetValue(Grid.ColumnProperty, 1); } else { DirectionsScrollViewer.SetValue(Grid.RowProperty, 2);
DirectionsScrollViewer.SetValue(Grid.ColumnProperty, 0); } }

适应不同的分辨率:

在Grid中用"Auto"和"*"来表示高宽来保证好的布局:Auto表示自适应控件的尺寸,如果多行设置成*,刚平分剩下的空间。

<Grid>
   <Grid.RowDefinitions>
     <RowDefinition Height="240"/>
     <RowDefinition Height="*"/>
     <RowDefinition Height="Auto"/>
   </Grid.RowDefinitions>
...
 </Grid>

用Grid做自适应布局:

图片:大多数情况下,应该提供适应WXGA(1280*768)大小的图片,在WVGA时会自动缩小,在1280*720时也很不错。当然也可以提供3种分辨率的图片,在运行时,通过Application.Current.Host.Content.ScaleFactor取得分辨率,WVGA则返回100,WXGA返回150,720P返回160。

启动画面:添加一个1280*720的SpalshScreenImage.jpg到工程中即可。如果想提供精通到象素的图片的话,还需要提供SplashScreenImage.Screen-WVGA.jpg,SplashScreenImage.Screen-WXGA.jpg,SplashScreenImage.Screen-720p.jpg除了这三张图片,原来的SpalshScreenImage.jpg也还不能删。

程序图标和磁贴:必须提供适应WXGA的图片,系统会自动缩放至合适的大小。


Windows Phone 8 语言支持:支持显示50种语言,包括从右向左的语言。

内置本地化项目模板:在Visual Studio 2012建的每个项目中,会自带一个LocalizedStrings类,简单地提供了存取资源的代码,并在App.XAML里添加了一个程序级的资源,每个项目都包括一个资源文件,即Resources\AppResources.resx,并且在MainPage.xaml.cs里也包括一块注释了的代码,这块代码是用来帮助本地化ApplicationBar的。

XAML中存取字符串资源:在数据绑定到控件时,将Text属性绑定到StaticResource外加LoczlizeString的key。

定义中立语言:设置默认的文化以匹配默认资源文件中的字符串:右键项目名称,选择属性,在Application选项卡上,选择Assembly Information,在中立语言列里,选择默认文化,这里让资源文件和语言和文化匹配。

定义所有支持的语言:双击WMApplication.XML文件,在Packaging选项卡中,设置默认语言,然后选中所有支持的语言。


Windows Phone Toolkit:原来叫Silverlight Toolkit,主要是扩充官方控件集里没有的功能,开源,每3个月更新一次。

 
Nuget: .NET下的依赖库整理系统,开源,可以在Visual Studio 2012中通过Nuget获得Windows Phone Toolkit。
 
右键菜单:

时间和日期选择器:

状态切换器:

WrapPanel:

ListPicker:


页面过渡效果:包括Roll, Swivel, Rotate, Slide and Turnstile等方式。可以用toolkit中的TransitionFrame替代自带的PhoneApplicationFrame开始,在App.xaml.cs里设置InitializePhoneApplication()函数。

效果如下:

 在Page上允许过渡效果:

声明toolkit的引用:

在<Phone:PhoneApplicationPage>的根元素下,添加效果:

倾斜效果:

1,为控件的交互添加附加的视觉回馈。

2,替换原始自带的简单的Pressed, UnPressed状态。

3,在页面上为所有控件“开启”倾斜效果:

4,也可以只应用到单个控件: