原文: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. Django 使用模型的API

    进入项目目录 python3运行 import os os.environ['DJANGO_SETTINGS_MODULE']= '项目.settings' import django django. ...

  2. ASP.NET MVC从请求到响应发生了什么

    *过程描述 当浏览器发出一个http请求后,该请求被UrlRoutingModule截获,UrlRoutingModule根据请求上下文去系统路由表(RouteTable)中匹配,从中获取一个Rout ...

  3. AspNet Core2 浏览器缓存使用

    Core2中使用Microsoft.AspNetCore.Mvc下的ResponseCacheAttribute特性来控制Http Get请求的缓存 原理是设置http请求 响应头的Cache-con ...

  4. inode 耗尽

    背景: 之前为了提升大硬盘mkfs文件系统的速度,使用了大文件选项 mkfs.ext4 -T largefile /dev/xvde1 没有仔细算能存多少文件,结果今天发现磁盘没用完,但inode用完 ...

  5. office(Word、Excel、PPT等图标异常和桌面无新建解决方案)

    前言吐槽: 前不久因为安装了WPS,然后觉得不好用卸载WPS装回office就出现了一个很恶心的问题:word文档.excel文档.PPT这些办公软件图标异常,显示的是下面这样: 打开倒是可以正常用w ...

  6. 轻量级服务器部署方案 -(阿里云CenOS+宝塔)

    一台服务器部署多个应用.可部署前端工程.node服务.数据库等. 一.服务器选择合适的服务器,购买即可.服务器商1.阿里云 2.腾讯云 3.百度云 二.服务器管理面板-宝塔宝塔面板是一款服务器管理软件 ...

  7. kafka集群环境搭建(Linux)

    一.准备工作 centos6.8和jvm需要准备64位的,如果为32位,服务启动的时候报java.lang.OutOfMemoryError: Map failed 的错误. 链接:http://pa ...

  8. jQuery 往table添加新内容有以下四个方法:

    Query 添加新内容有以下四个方法: append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() ...

  9. ST_Geometry效率的测试与分析

    测试环境 数据库:Oracle11g R1(11.1.0.6) 64Bit 中间件:ArcSDE10 (64Bit) 数据情况:点数据(point,231772条记录),面数据(poly,12条记录) ...

  10. 视频播放flv player的使用

    JW FLV PLAYER 中文文档 使用方法:如果你仅需要播放一个FLV文件[例如“video.flv”],那么只要把“video.flv”和压缩包内的 flvplayer.swf复制到同一个目录内 ...