原文: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列表项的更多相关文章

  1. WPF中的3D Wireframe

    原文:WPF中的3D Wireframe WPF不支持画三维线,但开发人员提供了ScreenSpaceLines3D 类用于实现这个功能.我已经在程序中实现并成功显示3D Wireframe,并能够进 ...

  2. WPF中的3D特性和常见的几个类

    原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1.  Visual 类      所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...

  3. 在WPF中添加3D特性

    原文:在WPF中添加3D特性 35.4  在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...

  4. WPF中的3D变换PlaneProjection

    在UWP中有一个比较好用的伪3D变换PlaneProjection,可以以一种轻量级和非常简单的方式实现3D的效果.这种效果在Silverlight中也有这种变换,但在WPF中确一直没有提供. 虽然W ...

  5. WPF中的事件列表 .

    以下是WPF中的常见事件汇总表(按字母排序),翻译不见得准确,但希望对你有用. 事件 描述 Annotation.AnchorChanged 新增.移除或修改 Anchor 元素时发生. Annota ...

  6. WPF中的三维空间(1)

    原文:WPF中的三维空间(1) WPF中可以创建三维几何图形,支持3D对象的应用,支持从3D Max等软件将3D文件obj导入设计中,但是目前还不支持将材质同时导入,这样需要在WPF中对3D对象重新设 ...

  7. 复制SharePoint列表项(SPListItem)到另一个列表

    从理论上讲,有一个简单到难以置信的解决办法:SPListItem提供了一个CopyTo(destinationUrl)方法(可参考MSDN).不幸的是,这个方法似乎用不了.至少对我的情况(一个带附件的 ...

  8. 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询

    前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...

  9. SharePoint REST API - 列表和列表项

    博客地址:http://blog.csdn.net/FoxDave 本篇主要讲述如何用SharePoint REST操作列表和列表项.阅读本篇时请先了解前面讲述的REST介绍和基本操作. 废话不多 ...

随机推荐

  1. Android JNI c/c++调用java 无需新建虚拟机

    近期通过研究SDL源码 得出android JNI  c/c++调用java 无需新建虚拟机: 具体步骤如下 第一步获得:两个参数 JNIEnv和jclass void Java_com_Test_A ...

  2. TraceView工具的使用

    一.TraceView工具如何使用 TraceView有4种启动/关闭分析方式: (1) 第一种使用方法演示 1. 选择跟踪范围 在想要根据的代码片段之间使用以下两句代码 Debug.startMet ...

  3. 【Java入门提高篇】Day34 Java容器类详解(十五)WeakHashMap详解

    源码详解系列均基于JDK8进行解析 说明 在Java容器详解系列文章的最后,介绍一个相对特殊的成员:WeakHashMap,从名字可以看出它是一个 Map.它的使用上跟HashMap并没有什么区别,所 ...

  4. Ubuntu切换root身份,命令行以中文显示

    很多VPS商给的默认用户名并不是root,用以下命令处理即可: 1.修改root密码 sudo passwd root 输入密码,回车,再确认一次即可 2.更改密码后切换root身份 su root ...

  5. (网页)JS中的小技巧,但十分的实用!

    转自CSDN: 1.document.write(”"); 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head,body)4. ...

  6. Python笔记(十四):操作excel openpyxl模块

    (一)  常遇到的情况 就我自己来说,常遇到的情况可能就下面几种: 读取excel整个sheet页的数据. 读取指定行.列的数据 往一个空白的excel文档写数据 往一个已经有数据的excel文档追加 ...

  7. etcd raft如何实现Linearizable Read

    Linearizable Read通俗来讲,就是读请求需要读到最新的已经commit的数据,不会读到老数据. 对于使用raft协议来保证多副本强一致的系统中,读写请求都可以通过走一次raft协议来满足 ...

  8. Linux主机定期打补丁修复漏洞

    1.如图扫描出来的漏洞 不看不知道,一看吓一跳  2.Linux主机如何扫描漏洞 参照:Linux操作系统下查找漏洞的几种必备兵器 3.linux操作系统怎么样打补丁?linux系统升级软件 使用yu ...

  9. java -jar 命令

    java -jar spring.jar 这个命令当你 controller c 之后,程序就自动结束了 java jar spring.jar & &是指在后台运行,但当用户推出(挂 ...

  10. tomcat 7.0 最大连接数和线程设置

    部署项目时需要根据服务器配置调整连接数 <Connector port="8080" protocol="HTTP/1.1"URIEncoding=&qu ...