WPF中反转3D列表项
原文:WPF中反转3D列表项
WPF中反转3D列表项
周银辉
记得在苹果电脑中有一个很酷的3D旋转效果, 它可以将某项的正反面进行反转, 在WPF中可以很轻松地做到该效果.
点击这里查看也可以粘贴此代码XamlPad中查看:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<x:Array Type="{x:Type s:String}" x:Key="src">
<s:String>Foo</s:String>
<s:String>Bar</s:String>
<s:String>Spong</s:String>
<s:String>One</s:String>
<s:String>Two</s:String>
<s:String>Three</s:String>
<s:String>Four</s:String>
<s:String>Five</s:String>
</x:Array>

<DataTemplate x:Key="frontTemplate">
<GroupBox Header="Front" Background="White">
<TextBlock FontSize="40" Foreground="Green" Text="{Binding}" />
</GroupBox>
</DataTemplate>
<DataTemplate x:Key="backTemplate">
<GroupBox Header="Back" Background="White">
<StackPanel>
<RadioButton Content="This" IsChecked="True" />
<RadioButton Content="Is" />
<RadioButton Content="The" />
<RadioButton Content="Back" />
</StackPanel>
</GroupBox>
</DataTemplate>
<DataTemplate x:Key="flipItemTemplate">
<!-- Note: Camera setup only works when this is square. -->
<Grid Width="200" Height="200">
<!-- Provides 3D rotation transition. Hidden except for when animation is
active. -->
<Viewport3D Grid.Column="0" x:Name="vp3D" Visibility="Hidden">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera" Position="0,0,0.5" LookDirection="0,0,-1" FieldOfView="90" />
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Color="#444" Direction="0,0,-1" />
<AmbientLight Color="#BBB" />
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>

<!-- Simple flat, square surface -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 2,3,0"
TextureCoordinates="0,1 1,1 1,0 0,0"
Positions="-0.5,-0.5,0 0.5,-0.5,0 0.5,0.5,0 -0.5,0.5,0" />
</GeometryModel3D.Geometry>

<!-- Front of shape shows the content of 'frontHost' -->
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<VisualBrush Visual="{Binding ElementName=frontHost}" />
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>

<!-- Back of shape shows the content of 'backHost' -->
<GeometryModel3D.BackMaterial>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<VisualBrush Visual="{Binding ElementName=backHost}">
<VisualBrush.RelativeTransform>
<!-- By default, this would come out backwards because we're on the
back on the shape. Flip it to make it right. -->
<ScaleTransform ScaleX="-1" CenterX="0.5" />
</VisualBrush.RelativeTransform>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.BackMaterial>
<!-- Rotation transform used for transition. -->
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotate" Axis="0,3,0" Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
<!-- We use a pair of nested Borders to wrap the content that's going to go on
each side of the rotating model.
The reason is that we need to be able to fade these real bits of UI in and out
as we transition from front to back, but we need to make sure the VisualBrush
in the 3D model doesn't also get faded out. So the VisualBrush uses the inner
Border, while the fade is applied to the outer one.
-->
<Border x:Name="frontWrapper">
<!-- Note, it's important that this element has visuals that completely fill the space, as
otherwise it messes with the VisualBrush's size in the 3D model. Setting the background
has that effect, even a transparent one. -->
<Border x:Name="frontHost" Background="Transparent">
<Border.Triggers>
<EventTrigger RoutedEvent="Grid.MouseDown">
<BeginStoryboard>
<Storyboard>
<!-- Make the Viewport3D visible only for the duration of the rotation. -->
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="vp3D"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
<DiscreteObjectKeyFrame KeyTime="0:0:1.1" Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<!-- Make the background element visible. (It won't actually appear until it is
faded in right at the end of the animation.) -->
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="backWrapper"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>

<!-- Hide the foreground element. It will already be invisible by this time
because we fade it out right at the start of the animation. However, until
we set its Visibility to Hidden, it will still be visible to the mouse
-->
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="frontWrapper"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.05" Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>

<!-- Fade the front wrapper out. The Viewport3D is behind us, so it'll fade into
view at this point. The reason for fading is to avoid a visible step as we
switch from the real UI to the copy projected onto the 3D model. -->
<DoubleAnimation To="0" Duration="0:0:0.05"
Storyboard.TargetName="frontWrapper"
Storyboard.TargetProperty="Opacity" />
<!-- Fade the back wrapper in. Once the spin completes, we fade the real back UI
in over the Viewport3D - using a fade to avoid a sudden jolt between the
slightly fuzzy 3D look and the real UI. -->
<DoubleAnimation BeginTime="0:0:1.05" Duration="0:0:0.05" To="1"
Storyboard.TargetName="backWrapper"
Storyboard.TargetProperty="Opacity" />
<!-- 3D animation. Move the camera out slightly as we spin, so the model fits entirely
within the field of view. Rotate the model 180 degrees. -->
<Point3DAnimation To="0,0,1.1" From="0,0,0.5"
BeginTime="0:0:0.05" Duration="0:0:0.5" AutoReverse="True" DecelerationRatio="0.3"
Storyboard.TargetName="camera"
Storyboard.TargetProperty="(PerspectiveCamera.Position)" />
<DoubleAnimation From="0" To="180" AccelerationRatio="0.3" DecelerationRatio="0.3"
BeginTime="0:0:0.05" Duration="0:0:1"
Storyboard.TargetName="rotate"
Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource frontTemplate}" />
</Border>
</Border>
<Border x:Name="backWrapper" Grid.Column="0" Visibility="Hidden" Opacity="0">
<Border x:Name="backHost" Background="Transparent">
<Border.Triggers>
<EventTrigger RoutedEvent="Grid.MouseDown">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="vp3D"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
<DiscreteObjectKeyFrame KeyTime="0:0:1.1" Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="frontWrapper"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="backWrapper"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.05" Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation To="0" Duration="0:0:0.05"
Storyboard.TargetName="backWrapper"
Storyboard.TargetProperty="Opacity" />
<DoubleAnimation BeginTime="0:0:1.05" Duration="0:0:0.05"
Storyboard.TargetName="frontWrapper"
Storyboard.TargetProperty="Opacity" />
<Point3DAnimation To="0,0,1.1" From="0,0,0.5"
BeginTime="0:0:0.05" Duration="0:0:0.5" AutoReverse="True" DecelerationRatio="0.3"
Storyboard.TargetName="camera"
Storyboard.TargetProperty="(PerspectiveCamera.Position)" />
<DoubleAnimation From="180" To="360" AccelerationRatio="0.3" DecelerationRatio="0.3"
BeginTime="0:0:0.05" Duration="0:0:1"
Storyboard.TargetName="rotate"
Storyboard.TargetProperty="Angle" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource backTemplate}" />
</Border>
</Border>

</Grid>
</DataTemplate>
</Page.Resources>
<ScrollViewer>
<ItemsControl ItemsSource="{StaticResource src}" ItemTemplate="{StaticResource flipItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>

</Page>

更多请参考这里: http://www.interact-sw.co.uk/iangblog/2007/05/17/wpf-flippable-3D-list
WPF中反转3D列表项的更多相关文章
- WPF中的3D Wireframe
原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能.我已经在程序中实现并成功显示3D Wireframe,并能够进 ...
- WPF中的3D特性和常见的几个类
原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1. Visual 类 所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...
- 在WPF中添加3D特性
原文:在WPF中添加3D特性 35.4 在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...
- WPF中的3D变换PlaneProjection
在UWP中有一个比较好用的伪3D变换PlaneProjection,可以以一种轻量级和非常简单的方式实现3D的效果.这种效果在Silverlight中也有这种变换,但在WPF中确一直没有提供. 虽然W ...
- WPF中的事件列表 .
以下是WPF中的常见事件汇总表(按字母排序),翻译不见得准确,但希望对你有用. 事件 描述 Annotation.AnchorChanged 新增.移除或修改 Anchor 元素时发生. Annota ...
- WPF中的三维空间(1)
原文:WPF中的三维空间(1) WPF中可以创建三维几何图形,支持3D对象的应用,支持从3D Max等软件将3D文件obj导入设计中,但是目前还不支持将材质同时导入,这样需要在WPF中对3D对象重新设 ...
- 复制SharePoint列表项(SPListItem)到另一个列表
从理论上讲,有一个简单到难以置信的解决办法:SPListItem提供了一个CopyTo(destinationUrl)方法(可参考MSDN).不幸的是,这个方法似乎用不了.至少对我的情况(一个带附件的 ...
- 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询
前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...
- SharePoint REST API - 列表和列表项
博客地址:http://blog.csdn.net/FoxDave 本篇主要讲述如何用SharePoint REST操作列表和列表项.阅读本篇时请先了解前面讲述的REST介绍和基本操作. 废话不多 ...
随机推荐
- C# 6 元组应用 Part 2:C# 也玩模式匹配
C# 7给我们带来了一个半吊子的 switch 语句模式匹配,只能简单的匹配类型而已,完全没有什么用处.这里我提供个更好的简单实现,用 C# 6 的 ValueTuple 模拟函数式语言的模式匹配功能 ...
- Apex简介
Apex特点 Salesforce为开发者提供了Apex语言.它是一种语法上类似于Java的编程语言,有以下特点: 面向对象 完全在云端处理,包括保存.编译.执行 强类型 大小写不敏感(这一点和其他大 ...
- 安卓开发_数据存储技术_sqlite
一.SQLite SQLite第一个Alpha版本诞生于2000年5月,它是一款轻量级数据库,它的设计目标是嵌入式的,占用资源非常的低,只需要几百K的内存就够了.SQLite已经被多种软件和产品使用 ...
- Android basics
只要是Android中的控件,最终都继承自View.
- Flume Source 实例
Flume Source 实例 Avro Source 监听avro端口,接收外部avro客户端数据流.跟前面的agent的Avro Sink可以组成多层拓扑结构. 1 2 3 4 5 6 7 8 9 ...
- MySQL写入用户微信名
很简单的需求,将用户微信名写入MySQl即可,但是测试过程中却遇到了问题,微信名中的emoji写入数据库失败.解决步骤如下 1.了解utf8mb4 MySQL从5.5.3版本开始支持utf8mb4编码 ...
- NoSQL&Redis
1.介绍NoSQL NoSQL(Not Only SQL):不仅仅是SQL,是一项全新的数据库理念,泛指非关系型数据库,原来我们所使用的MySQL.Oracle.Microsoft SQL Serve ...
- HDU ACM 1869 六度分离(Floyd)
六度分离 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- JMeter乱码常见的解决方案
方法一.直接将JMeter中http请求中Content encoding改为utf-8 方法二.编辑JMeter安装目录:apache-jmeter-3.2\bin中的jmeter.properti ...
- 【PAT】B1036 跟奥巴马一起编程(15)(15 分
#include<stdio.h> int main() { int row,col; char c; scanf("%d %c",&col,&c); ...