吴佳鑫的个人专栏

当日事当日毕,没有任何借口

导航

修炼九阴真经Windows Phone开发 (13):Panorama全景模式概述与应用

一、概述

Panorama控件是Windows Phone 7中一个很特别的控件,它给用户提供一种很好的使用体验。

Panorama控件通过使用一个超过屏幕宽度的长水平画布,提供了一种独特显示控件、数据和服务的方式。

 

Panorama控件用来在一个很长的横向面板上显示相关的内容,屏幕之外的内容可以依次切入到屏幕中,可以通过左右滑动的方式来切换它们。当看到其中的一个元素的时候,可以在屏幕右边显示出了一点下一屏的内容,这样你就可以知道在当前屏幕的下一屏还是有内容的。当浏览到内容的最后一屏再继续切换的话,则会回到第一屏。另外Panorama控件自身内置了触控和导航,通常来说这些已经够用,基本上不需要再为其实现特殊的手势功能。

在Windows Phone系统下,内置的People和Music+Videos界面就是一个典型的案例。下图就是在People界面下的Panorama界面效果。

clip_image001

 

上图这个长的画布就可以看作是一个全景视图,手机当前显示“all”这一部分,在屏幕上向左滑动手指,就可以切换到显示“what’s new”部分。

 

 

二、整体结构

那我们来看看Panorama的整体结构:

全景体验由全景背景、全景控件标题,和一个或多个的全景 PanoramaItem控件组成,基于应用程序的要求,PanoramaItem控件所呈现的视觉内容可以多样化。

 

UI_Panorama_04

AP_CoreCon_PanoAnatomyCon

蓝色线部分是整个Panorama的宽度,红色线表示手机屏幕的宽度。屏幕的宽度比要显示的Content(内容)区域略宽,下一个Content区域的一部分会在当前位置显示出来,就像第一幅图中所示,在当前页面“all”中,会显示出它的后一个页面“what’s new”的左侧边界区域,在用户导航操作时,可以预览到下一个页面的一小部分内容,这样做使用户体验更好。

 

Panorama 控件是用于全景应用程序的基础控件,该控件包含三个不同的层。每个层都包含在用作 Panorama 控件的布局根的 Grid 控件中。

  • 背景

  • 标题

 

类型

说明

背景

PanningBackgroundLayer

用于显示背景和设置背景动画的面板。

标题

PanningTitleLayer

用于显示标题和设置标题动画的面板。

PanningLayer

显示 PanoramaItem 控件的层。

在任何层上执行拖动或平移将导致您应用程序中的所有三个层一起移动。

背景层Background Layer

背景层是使用 Panorama 控件上的 Background 属性设置的。不应该将全景控件的 Background 设置为 null。如果设置为 null,则手势响应将不可靠。在默认模板中,Background 在默认情况下设置为 Transparent

您可以应用以下画笔:

  • SolidColorBrush:对背景应用一种颜色。

  • ImageBrush:对背景应用图像。

  • GradientBrush:可以对背景使用线性或径向画笔。

所有背景画笔都将被垂直拉伸以填充 Panorama 控件的高度。ImageBrush 将保留 ImageSource 的宽度,GradientBrush 将被拉伸以填充各项的宽度。

注意:

建议使用图片的高为800像素,宽度大于480像素,但是不要超过2000像素。高度不足800像素图片会被拉伸,超过2000像素图片将会被裁减。

Panorama的背景图片,其Build Action属性一定要设置为Resource,否则在Panorama第一次显示时不会立刻显示出来。这是因为Build Action属性设置为Content导致资源的异步加载。在其它资源的使用中也应该注意到这点。

重要说明 重要说明:

如果某个 Panorama 控件使用图像作为背景,则它的“生成操作”应该设置为“资源”;否则,当第一次显示应用程序时该控件不会立即显示。将“生成操作”设置为“内容”将导致它异步加载。

标题层Title Layer

 

整个全景视图的标题,即图片中最大的文字“Panorama”(它太大了,没有完全显示出来)。

 

该层是全景应用程序的标题并且它是在 Panorama 控件的 Title 属性中设置的。无论内容大小是否过大还是缺少内容,该层使用的垂直高度都不变。当您平移经过内容的边缘时,该层也不会重复自己。在选择在 PanoramaItem 控件之间更改期间,该层采用动画的形式在之前移动的方向脱离视图并从屏幕的另一侧回到场景。

不过需要注意的是,即使它显得很不协调,建议还是不要修改它的高度。我们可以理解为:这样做是为了保证所有应用程序中的全景视图其外观能够保持统一的风格。

 

通过Panorama的HeaderTemplate属性,可以改变它的Tiltle,比如修改字体、颜色,甚至添加一些其它的控件。不过建议不要这样做,修改颜色还好,修改其它的会出现一些怪异的问题。但要注意Title的颜色要与背景协调。避免动态的改变Tiltle的大小,避免使用动画效果的Title。

 

注意 注意:

如果您从标题中删除文本,则填充将仍然留在该控件上。您可以修订模板标题以占用所需的任意空间。但是,这将不符合 Windows Phone 设计准则。

项层Items Layer

项层是将包含 PanoramaItem 控件的层。这是用户在应用程序中主要交互的层。该层通过平移手势采用 1:1 的方式移动,因此从平移开始到手指抬起,手指下的内容保持不变。

PanormaItem控件

 

包含全景视图中的所有Panorama Item的集合,也就是上图所示的绿色和蓝色框区域。

建议在全景视图中最多不要加入超过4个Item。在Item中可以放置比屏幕宽度宽的控件,例如:放置一个Grid控件,将其宽度设置为800,是没问题的。

很明显Item分为两个部分:

Header

绿色框区域是Panorama Item的标题。建议这个标题的名称不要过长(屏幕显示不下当然看着不爽)。

Content

蓝色框区域是Panorama Item的内容,我们要展示的控件就会放到这个区域当中了。


PanoramaItem 控件是添加到 Panorama 控件的内容的各个部分。Panorama 控件可以支持多个 PanoramaItem 控件并且用户可以使用支持的触控手势浏览这些部分。PanoramaItem 控件自身由两个元素组成。每个元素都包含在用作 PanoramaItem 控件的布局根的 Grid 中。

  • 标头

  • 内容

 

元素

类型

说明

标头

ContentControl

用于显示标头和设置标头动画的 ContentControl。此标头可选。如果未指定,则不应该为了节省空间而进行折叠。

内容

ContentPresenter

显示 PanoramaItem 内容的 ContentPresenter

可以在 XAML 代码中指定 PanoramaItem 控件的内容,也可以采用编程方式通过 Content 属性添加该控件的内容。

PanoramaItem 控件既支持水平方向,也支持垂直方向。下面是这些方向的特性:

  • PanoramaItem 控件的垂直方向在手势移动期间将只能对齐到屏幕的左侧。

  • PanoramaItem 控件的水平方向在手势移动期间将能够对齐到屏幕的左侧和右侧。

  • PanoramaItem 控件设置为水平方向将允许在屏幕外放置内容,而不是裁剪内容。

  • 与垂直方向不同,水平方向将允许用户在内容中心平移,但不对齐到新的 PanoramaItem 控件视图。

 

三、创建方法和应用

 

在项目中填加全景控件方法:

 

可以通过三种方式填加它们。

 

1、工具栏

 

直接从工具栏拖拽的方式在现有页面中填加它们,但默认这两个控件是不在工具栏中的,要让他们出现在这里,需要右键工具栏然后选择Choose Items。

 

clip_image003

 

2、使用页面模版

 

在解决方案管理器中右键项目,点Add->New Item。在新建项目对框框中,选择Windows Phone Panorama Page或者Windows Phone Pivot Page。

 

clip_image004

 

3、通过项目模版

 

新建一个项目,项目类型选择Windows Phone Panorama Application或者Windows Phone Pivot Application。

 

clip_image005

 

无论以这三种方式的哪种方式使用这两个控件,下面的程序集都会被自动填加。

 

Microsoft.Phone.Controls.dll

 

同样如下的XML命名空间也会被填加到页面。

 

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

 

 

  

 

 

 

 

  使用第三种方法新建后VS将自动产生Panorama项目模板,这种方法比较简单。如下图

 

  

 

 

 

 

  

 

 

  2.图1步骤

 

  从工具箱中拖Panorama控件到视图工作区,在本例中一共有四页,第一页是一个ListBox控件,第二页是一个Ellipse控件,第三页是一个多行文本区域控件(TextBlock),第四页是一个具有动画效果的文本,我们可以通过左右滑动来进行换页,大家或许已经看出它和Pivot的差别,在一页中它可以看到部分属于第二页的东东,而且它的标题Title横跨整个Panorama布局

 

 

 

<controls:Panorama Title="panorama 演示" x:Name="panorama">
<controls:PanoramaItem Header="ListBox">
<ListBox FontSize="{StaticResource PhoneFontSizeLarge}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
FontFamily=
"{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>

<system:String>Arial</system:String>
<system:String>Arial Black</system:String>
<system:String>Calibri</system:String>
<system:String>Comic Sans MS</system:String>
<system:String>Courier New</system:String>
<system:String>Georgia</system:String>
<system:String>Lucida Sans Unicode</system:String>
<system:String>Portable User Interface</system:String>
<system:String>Segoe WP</system:String>
<system:String>Segoe WP Black</system:String>
<system:String>Segoe WP Bold</system:String>
<system:String>Segoe WP Light</system:String>
<system:String>Segoe WP Semibold</system:String>
<system:String>Segoe WP SemiLight</system:String>
<system:String>Tahoma</system:String>
<system:String>Times New Roman</system:String>
<system:String>Trebuchet MS</system:String>
<system:String>Verdana</system:String>
<system:String>Webdings</system:String>
</ListBox>
</controls:PanoramaItem>

<controls:PanoramaItem Header="Ellipse">
<Ellipse>
<Ellipse.Fill>
<LinearGradientBrush>
<GradientStop Offset="0" Color="{StaticResource PhoneAccentColor}" />
<GradientStop Offset="0.5" Color="{StaticResource PhoneBackgroundColor}" />
<GradientStop Offset="1" Color="{StaticResource PhoneForegroundColor}" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</controls:PanoramaItem>

<controls:PanoramaItem Header="TextBlock">
<ScrollViewer>

<TextBlock TextWrapping="Wrap">
For a long time I used to go to bed early. Sometimes, when I had put out
my candle, my eyes would close so quickly that I had not even time to
say "I'm going to sleep." And half an hour later the thought that it was
time to go to sleep would awaken me; I would try to put away the book
which, I imagined, was still in my hands, and to blow out the light; I
had been thinking all the time, while I was asleep, of what I had just
been reading, but my thoughts had run into a channel of their own,
until I myself seemed actually to have become the subject of my book:
a church, a quartet, the rivalry between François I and Charles V. This
impression would persist for some moments after I was awake; it did not
disturb my mind, but it lay like scales upon my eyes and prevented them
from registering the fact that the candle was no longer burning. Then
it would begin to seem unintelligible, as the thoughts of a former
existence must be to a reincarnate spirit; the subject of my book would
separate itself from me, leaving me free to choose whether I would form
part of it or no; and at the same time my sight would return and I
would be astonished to find myself in a state of darkness, pleasant and
restful enough for the eyes, and even more, perhaps, for my mind, to
which it appeared incomprehensible, without a cause, a matter dark
indeed.
</TextBlock>
</ScrollViewer>
</controls:PanoramaItem>

<controls:PanoramaItem Header="Animation">
<TextBlock Text="Hello, Windows Phone 7!"
HorizontalAlignment=
"Left"
VerticalAlignment=
"Top"
RenderTransformOrigin=
"0.5 0.5">
<TextBlock.RenderTransform>
<CompositeTransform x:Name="xform" />
</TextBlock.RenderTransform>

</TextBlock>

<controls:PanoramaItem.Triggers>
<EventTrigger>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="xform"
Storyboard.TargetProperty=
"Rotation"
From=
"0" To="360" Duration="0:0:3"
RepeatBehavior=
"Forever" />

<DoubleAnimation Storyboard.TargetName="xform"
Storyboard.TargetProperty=
"TranslateX"
From=
"0" To="300" Duration="0:0:5"
AutoReverse=
"True"
RepeatBehavior=
"Forever" />

<DoubleAnimation Storyboard.TargetName="xform"
Storyboard.TargetProperty=
"TranslateY"
From=
"0" To="600" Duration="0:0:7"
AutoReverse=
"True"
RepeatBehavior=
"Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</controls:PanoramaItem.Triggers>
</controls:PanoramaItem>
</controls:Panorama>

 

  效果如图

 

  

 

 

 

 

  3.数据绑定

 

  1)数据源类Datas.cs

 

public static class Datas
{
public static List<string> GetDatas()
{
List<string> list = new List<string>();
list.Add("salam");
list.Add("Aiming Zhang");
return list;
}
}

 

 

 

  2)MainPage.cs

 

public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.panorama.ItemsSource = Datas.GetDatas();
}
}

 

 

 

  效果如图

 

  

 

 
 
 
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Pivot控件示例

下面示例创建一个Pivot控件显示用户任务中的不同视图。其中有三个PivotItem控件,每个部分根据全部任务,今日任务和明日任务来过滤数据。

XAML

<!--LayoutRoot is the root grid where all page content is placed-->

<Grid x:Name="LayoutRoot" Background="Transparent">

<controls:Pivot Title="my tasks">

<!--Pivot item one-->

<controls:PivotItem Header="all">

<ListBox FontSize="30">

<ListBoxItem Content="Dentist appointment" />

<ListBoxItem Content="Pickup laundry" />

<ListBoxItem Content="Service car" />

<ListBoxItem Content="Send birthday gift to mom" />

<ListBoxItem Content="Grocery" />

</ListBox>

</controls:PivotItem>

<!--Pivot item two-->

<controls:PivotItem Header="today">

<ListBox FontSize="30">

<ListBoxItem Content="Dentist appointment" />

<ListBoxItem Content="Pickup laundry" />

</ListBox>

</controls:PivotItem>

<!--Pivot item three-->

<controls:PivotItem Header="tomorrow">

<ListBox FontSize="30">

<ListBoxItem Content="Service car" />

<ListBoxItem Content="Send birthday gift to mom" />

<ListBoxItem Content="Grocery" />

</ListBox>

</controls:PivotItem>

</controls:Pivot>

</Grid>

下图是运行结果。

clip_image007

提示:

如果要在这两个控件中实现纵向浏览,可以在其中填加滚动控件,比如ListBox,或者填加一个ScrollViewer。ScrllViewer可以确保元素尺寸始终都是跟容器搭配的。

 

 

 

 

注意:

在新建的工程里,可以看到PanoramaBackground.png这个图片,它就是全景视图的背景图了,可以更换这张图来满足自已需要。

<controls:Panorama.Background>

        <ImageBrush ImageSource="Panoramabg.png"/>

    </controls:Panorama.Background>

 

 

也可以动态添加

 

 

 

PanoramaItem item = new PanoramaItem();

panorama1.Items.Add(item);

 

 

posted on 2012-05-01 16:25  _eagle  阅读(1327)  评论(0编辑  收藏  举报