什么是SemanticZoom? 不了解的同学可以先看下这篇文章
http://technet.microsoft.com/zh-cn/subscriptions/hh781234
语义变焦(Semantic Zoom)是Windows8上一个新的触摸优化功能,它用新的视角来呈现和导航大量数据内容,利用延时加载来控制数据的展示。因此,它可以作为大批量数据的容器,用来展示单一或大数据集。通过语义变焦,用户可以使用“放大”来关注单一记录,使用“缩小”用其他想要的视角来查看一组数据。从这个意义上,用户能够选择数据组或部分、“放大”然后自动导航到选中的记录。
实现ISemanticZoomInformation或 IZoomableView的接口才能使用语义变焦。截至本文写作之时,仅GridView和ListView两种视图实现。此外,这两种视图可以根据用户操作来互相切换。
微软开发者布道师Jerry Nixon指出:“语义变焦只是通过两种视角来展示数据,并没有改变数据范围”。用触摸式界面提供的捏放手势和鼠标滑轮结合Control键都可以执行语义变焦,作为可选的,也可用Ctrl+和Ctrl-两个组合键。
语义变焦不同于排列图像时为让图像局部放大而用鼠标滑轮做的缩放操作。另外一方面,它也不同于为放大特别位置(例如Bing地图)上某些内容用鼠标做的光学变焦。
Developer Express公司软件工程师Mehul Harry指出“语义变焦是很酷的功能, Windows 8平台一定会让我们兴奋不已”。
上面一段文章 所介绍的SemanticZoom 将是本文的重点
那么如何将SemantciZoom 在其他控件中实现呢?下面我们来介绍如何实现SemanticZoomFlipView
可以语义变焦的FlipView
首先我们需要 建一个类
public class SemanticZoomFlipView : FlipView, ISemanticZoomInformation
用于继承FlipView 以及ISemanticZoomInformation
这时我们该类已经具备了FlipView的特性,那么 接下来需要实现 ISemanticZoomInformation这个接口 来完成语义变焦
// 摘要:
// 获取或设置指示实现视图是否为活动视图的值。
//
// 返回结果:
// 如果实现视图是活动视图,则为 true;否则为 false。
bool IsActiveView { get; set; }
//
// 摘要:
// 获取或设置一个值,该值指示实现视图是否是语义更为完整的放大视图。
//
// 返回结果:
// 如果实现视图是放大视图,则为 true;否则为 false。
bool IsZoomedInView { get; set; }
//
// 摘要:
// 获取或设置承载实现视图的 SemanticZoom 所有者。
//
// 返回结果:
// 承载此视图的 SemanticZoom。
SemanticZoom SemanticZoomOwner { get; set; }
// 摘要:
// SemanticZoom 的整体视图更改时,将更改表示形式的相关方面(例如滚动 UI 或状态)。
void CompleteViewChange();
//
// 摘要:
// 实现的视图是源视图,而新视图是可能不同的实现视图时,完成与视图更改相关的项操作。
//
// 参数:
// source:
// 显示在源视图中的视图项。
//
// destination:
// 显示在目标视图中的视图项。
void CompleteViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination);
//
// 摘要:
// 实现的视图是目标视图,而源视图是可能不同的实现视图时,完成与视图更改相关的项操作。
//
// 参数:
// source:
// 显示在源视图中的视图项。
//
// destination:
// 显示在目标视图中的视图项。
void CompleteViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination);
//
// 摘要:
// SemanticZoom 的整体视图将要更改时,初始化对表示的相关方面(例如滚动 UI 或状态)的更改。
void InitializeViewChange();
//
// 摘要:
// 强制视图中的内容滚动,直到看到 SemanticZoomLocation 指定的项。如果找到,还聚焦该项。
//
// 参数:
// item:
// 在视图中要滚动到的项。
void MakeVisible(SemanticZoomLocation item);
//
// 摘要:
// 实现的视图是源视图,而挂起的目标视图是可能不同的实现视图时,初始化与视图更改相关的项操作。
//
// 参数:
// source:
// 显示在源视图中的视图项。
//
// destination:
// 显示在目标视图中的视图项。
void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination);
//
// 摘要:
// 源视图是不同的视图,而挂起的目标视图是实现的视图时,初始化与视图更改相关的项操作。
//
// 参数:
// source:
// 显示在源视图中的视图项。
//
// destination:
// 显示在目标视图中的视图项。
void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination);
以上代码是该接口中的说明,当我们直接继承时 是可以实现语义变焦的,
但是 无法完成 所房中的定位,
例如我希望从A 字母 定位到 ZoomInVIew的 A字母块的话 就需要去实现这些方法。
接下来我是这么做的:
public void CompleteViewChange()
{
}
public void CompleteViewChangeFrom
(SemanticZoomLocation source, SemanticZoomLocation destination)
{
}
public void CompleteViewChangeTo
(SemanticZoomLocation source, SemanticZoomLocation destination)
{
}
public void InitializeViewChange()
{
}
private bool _IsActiveView;
public bool IsActiveView
{
get
{
return _IsActiveView;
}
set
{
_IsActiveView = value;
}
}
private bool _IsZoomedInView;
public bool IsZoomedInView
{
get
{
return _IsZoomedInView;
}
set
{
_IsZoomedInView = value;
}
}
public void MakeVisible(SemanticZoomLocation item)
{
}
private SemanticZoom _SemanticZoomOwner;
public SemanticZoom SemanticZoomOwner
{
get
{
return _SemanticZoomOwner;
}
set
{
_SemanticZoomOwner = value;
}
}
public void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
{
var info = SemanticZoomOwner.ZoomedOutView;
SemanticZoomLocation o = new SemanticZoomLocation();
o.Item = this.SelectedItem;
if (null != o)
info.StartViewChangeTo(o, o);
}
public void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
{
if (null != source.Item)
{
this.SelectedItem = source.Item;
destination.Item = source.Item;
}
}
当我在FlipView 中 确定了 SelectdItem的时候 FlipView 就会精准定位到 缩放的内容
当然 针对于其他控件的时候 比如内部包含ScrollView ,我们需要考虑他的 offset值,
这些值 将会通过 StartViewChangeFrom 来进行传输
public sealed class SemanticZoomLocation
{
// 摘要:
// 初始化 SemanticZoomLocation 类的新实例。
public SemanticZoomLocation();
// 摘要:
// 获取或设置当前 SemanticZoom 的视图中存在的项的大小界限。
//
// 返回结果:
// 项的大小界限。
public Rect Bounds { get; set; }
//
// 摘要:
// 获取或设置在当前 SemanticZoom 的视图中存在的显示项。
//
// 返回结果:
// SemanticZoom 中的特定项。
public object Item { get; set; }
}
拿到特定项之后我们就可以进行定位了
例如 我们拿到关键字A 那么 根据 该值 我们需要在 SemanticZoomIn里进行判断 该滑动到哪。
这样一个semanticFlipView 就完成了 接下来我们看下使用方法 和效果
<SemanticZoom
x:Name="sz"
IsZoomOutButtonEnabled="True"
IsZoomedInViewActive="{Binding IsZoomInActive, Mode=TwoWay}"
ViewChangeStarted="SemanticZoom_ViewChangeStarted" Grid.Row="1">
<SemanticZoom.Transitions>
<TransitionCollection>
<ContentThemeTransition></ContentThemeTransition>
</TransitionCollection>
</SemanticZoom.Transitions>
<SemanticZoom.ZoomedInView>
<control:SemanticZoomFlipView
x:Name="sfv"
SelectionChanged="sfv_SelectionChanged"
ItemsSource="{Binding SecondaryList}"
SelectedItem="{Binding SelectedSecondaryItem, Mode=TwoWay}"
ItemTemplateSelector="{StaticResource sfvDataTemplateaSelctor}"
Margin="0,0,0,0">
</control:SemanticZoomFlipView>
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
<GridView Grid.Row="1"
x:Name="gv"
Padding="100,0,0,0"
SelectionMode="None"
ScrollViewer.IsHorizontalScrollChainingEnabled="False"
ScrollViewer.IsVerticalScrollChainingEnabled="False"
SelectedItem="{Binding SelectedSecondaryItem, Mode=TwoWay}"
IsItemClickEnabled="True"
ItemsPanel="{StaticResource SecondaryItemsPanel}"
ItemTemplate="{StaticResource SecondaryZoomInItem}"
ItemsSource="{Binding SecondaryList}">
<GridView.Transitions>
<TransitionCollection>
<EntranceThemeTransition FromVerticalOffset="100" FromHorizontalOffset="100"/>
</TransitionCollection>
</GridView.Transitions>
</GridView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
我将 语义变焦Flipview 和GridView放在一起使用,当点击ZoomOutView的任意一项的时候FlipView会去定位到和该项关联的内容。
该效果视频请参考:
http://v.youku.com/v_show/id_XNDk0NzgyMDk2.html