原文: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--判断listview上下滑动的方法

    elv_music_res_fragment.setOnScrollListener(new AbsListView.OnScrollListener() { private int mLastFir ...

  2. 记一次nginx php配置的心路历程

    1.本来搞好了php的配置,想把目录下移一层 从 www.abc.com 变成 www.abc.com/wxapi ,由于我的真实文件目录比路由少了一层public 尝试了很多办法都不行 甚至想到了u ...

  3. 【redis专题(4)】命令语法介绍之sorted_set

    有序集合可以模拟优先级队列的实现 增 zadd key score1 value1 score2 value2 .. redis 127.0.0.1:6379> zadd stu 18 lily ...

  4. [20180705]关于hash join 2.txt

    [20180705]关于hash join 2.txt --//昨天优化sql语句,执行计划hash join right sna,加入一个约束设置XX字段not null,逻辑读从上万下降到50.- ...

  5. Android中使用databinding编译时出现的error:Execution failed for task ':app:dataBindingProcessLayoutsDebug'

    Windows环境下使用svn对AndroidStudio更新代码时,总会在源文件中出现一堆乱码,尤其是xml文件中的乱码,不仅找起来费劲,改起来更费劲. 最近从svn更新代码之后,编译时出现了下面这 ...

  6. ccf-20170303--Markdown

    我的想法如下图: 代码和题目如下: 问题描述 试题编号: 201703-3 试题名称: Markdown 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 Markdown 是一 ...

  7. 常见的web攻击方式

    跨站脚本攻击(XSS) 概述 跨站脚本攻击(XSS,Cross-site scripting),指攻击者在网页中嵌入恶意脚本程序,是最常见和基本的攻击WEB网站的方法.攻击者在网页上发布包含攻击性代码 ...

  8. CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场

    CF895C: Square Subsets && [BZOJ2844]albus就是要第一个出场 这两道题很类似,都是线性基的计数问题,解题的核心思想也一样. CF895C Squa ...

  9. [笔记]后缀数组SA

    参考资料这次是真抄的: 1.后缀数组详解 2.后缀数组-学习笔记 3.后缀数组--处理字符串的有力工具 定义 \(SA\)排名为\(i\)的后缀的位置 \(rk\)位置为\(i\)的后缀的排名 \(t ...

  10. ROS教程0 环境配置

    1安装环境配置(桌面进入命令行) echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc source ~/.bas ...