WPF如何实现类似iPhone界面切换的效果(转载)

时间:2022-09-05 22:18:57

WPF如何实现类似iPhone界面切换的效果 (version .1)

转自:http://blog.csdn.net/fallincloud/article/details/6968764

在论坛上见到有人提出了这个问题(WPF实现点击横向切换界面

我简单地做了个Sample。

效果图1:

WPF如何实现类似iPhone界面切换的效果(转载)

效果图2:

WPF如何实现类似iPhone界面切换的效果(转载)

设计思路

将这多个界面放入一个Orientation为Horizontal的StackPanel当中,点击Next时,里面所有控件执行TranslteTransform动画。

实现

xaml

  1. <Window x:Class="WPFNavigation.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="MainWindow" Height="350" Width="400">
  5. <Grid>
  6. <Grid.RowDefinitions>
  7. <RowDefinition Height="*"></RowDefinition>
  8. <RowDefinition Height="Auto"></RowDefinition>
  9. </Grid.RowDefinitions>
  10. <StackPanel Orientation="Horizontal"
  11. x:Name="NavigationPanel"
  12. Height="300"
  13. HorizontalAlignment="Left"
  14. VerticalAlignment="Top">
  15. <Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}, Path=ActualWidth }"
  16. Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type StackPanel}}, Path=ActualHeight}"
  17. Background="Blue" >
  18. <TextBlock FontSize="36">Page1</TextBlock>
  19. </Grid>
  20. <Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}, Path=ActualWidth }"
  21. Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type StackPanel}}, Path=ActualHeight}"
  22. Background="Violet">
  23. <TextBlock FontSize="36">Page2</TextBlock>
  24. </Grid>
  25. <Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}, Path=ActualWidth }"
  26. Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type StackPanel}}, Path=ActualHeight}"
  27. Background="Purple" >
  28. <TextBlock FontSize="36">Page3</TextBlock>
  29. </Grid>
  30. </StackPanel>
  31. <StackPanel Grid.Row="1"  Orientation="Horizontal" >
  32. <Button Content="Previous" x:Name="ButtonPreviousPage" Click="ButtonPreviousPage_Click"></Button>
  33. <Button Content="Next" x:Name="ButtonNextPage" Click="ButtonNextPage_Click"></Button>
  34. </StackPanel>
  35. </Grid>
  36. </Window>

cs中

    1. /// <summary>
    2. /// Interaction logic for MainWindow.xaml
    3. /// </summary>
    4. public partial class MainWindow : Window
    5. {
    6. private static readonly double COUNT_PAGE = 3;
    7. private TranslateTransform NavigationPanelTranslateTransform;
    8. public MainWindow()
    9. {
    10. InitializeComponent();
    11. NavigationPanelTranslateTransform = new TranslateTransform();
    12. this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
    13. }
    14. void MainWindow_Loaded(object sender, RoutedEventArgs e)
    15. {
    16. foreach (FrameworkElement fe in NavigationPanel.Children)
    17. {
    18. fe.RenderTransform = NavigationPanelTranslateTransform;
    19. }
    20. DeterminButtonStates();
    21. }
    22. private void DeterminButtonStates()
    23. {
    24. double currentTranX = NavigationPanelTranslateTransform.X;
    25. if (currentTranX >= 0)
    26. {
    27. ButtonPreviousPage.IsEnabled = false;
    28. }
    29. else if (currentTranX <= -(COUNT_PAGE - 1) * this.ActualWidth)
    30. {
    31. ButtonNextPage.IsEnabled = false;
    32. }
    33. else
    34. {
    35. ButtonPreviousPage.IsEnabled = true;
    36. ButtonNextPage.IsEnabled = true;
    37. }
    38. }
    39. private void ButtonPreviousPage_Click(object sender, RoutedEventArgs e)
    40. {
    41. double currentTranX = NavigationPanelTranslateTransform.X;
    42. DoubleAnimation da = new DoubleAnimation(currentTranX, currentTranX+this.ActualWidth, TimeSpan.FromMilliseconds(250));
    43. da.Completed += (o1, e1) =>
    44. {
    45. DeterminButtonStates();
    46. };
    47. NavigationPanelTranslateTransform.BeginAnimation(TranslateTransform.XProperty, da);
    48. }
    49. private void ButtonNextPage_Click(object sender, RoutedEventArgs e)
    50. {
    51. double currentTranX = NavigationPanelTranslateTransform.X;
    52. DoubleAnimation da = new DoubleAnimation(currentTranX, currentTranX - this.ActualWidth, TimeSpan.FromMilliseconds(250));
    53. da.Completed += (o1, e1) =>
    54. {
    55. DeterminButtonStates();
    56. };
    57. NavigationPanelTranslateTransform.BeginAnimation(TranslateTransform.XProperty, da);
    58. }
    59. }

WPF如何实现类似iPhone界面切换的效果 (version .2)

转自:http://blog.csdn.net/fallincloud/article/details/6969329

前面写了篇WPF如何实现类似iPhone界面切换的效果 (version .1)

现在又花了点时间重构了下,将动画的效果和Previous和Next这两个按钮的状态控制都封装了起来,效果依然和前面一样

不过重用性高了许多。使用方法如下:

XAML:

  1. <Window x:Class="WPFNavigation.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:local="clr-namespace:WPFNavigation"
  5. Title="MainWindow" Height="350" Width="400">
  6. <Grid>
  7. <Grid.RowDefinitions>
  8. <RowDefinition Height="*"></RowDefinition>
  9. <RowDefinition Height="Auto"></RowDefinition>
  10. </Grid.RowDefinitions>
  11. <local:NavigationPanel Orientation="Horizontal"
  12. x:Name="NavigationPanel"
  13. Height="300"
  14. HorizontalAlignment="Left"
  15. VerticalAlignment="Top">
  16. <Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}, Path=ActualWidth }"
  17. Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type local:NavigationPanel}}, Path=ActualHeight}"
  18. Background="Blue" >
  19. <TextBlock FontSize="36">Page1</TextBlock>
  20. </Grid>
  21. <Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}, Path=ActualWidth }"
  22. Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type local:NavigationPanel}}, Path=ActualHeight}"
  23. Background="Violet">
  24. <TextBlock FontSize="36">Page2</TextBlock>
  25. </Grid>
  26. <Grid Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}, Path=ActualWidth }"
  27. Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type local:NavigationPanel}}, Path=ActualHeight}"
  28. Background="Purple" >
  29. <TextBlock FontSize="36">Page3</TextBlock>
  30. </Grid>
  31. </local:NavigationPanel>
  32. <StackPanel Grid.Row="1"  Orientation="Horizontal" >
  33. <Button Content="Previous" x:Name="ButtonPreviousPage"
  34. IsEnabled="{Binding ElementName=NavigationPanel, Path=PreviousIsValid, Mode=OneWay}"
  35. Click="ButtonPreviousPage_Click"></Button>
  36. <Button Content="Next" x:Name="ButtonNextPage" Click="ButtonNextPage_Click"
  37. IsEnabled="{Binding ElementName=NavigationPanel, Path=NextIsValid, Mode=OneWay}"></Button>
  38. </StackPanel>
  39. </Grid>
  40. </Window>

C#:

  1. /// <summary>
  2. /// Interaction logic for MainWindow.xaml
  3. /// </summary>
  4. public partial class MainWindow : Window
  5. {
  6. public MainWindow()
  7. {
  8. InitializeComponent();
  9. }
  10. private void ButtonPreviousPage_Click(object sender, RoutedEventArgs e)
  11. {
  12. NavigationPanel.Previous();
  13. }
  14. private void ButtonNextPage_Click(object sender, RoutedEventArgs e)
  15. {
  16. NavigationPanel.Next();
  17. }
  18. }

以上是用法,封装的NavigationPanel设计如下:

WPF如何实现类似iPhone界面切换的效果(转载)

具体实现如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14. using System.Windows.Media.Animation;
  15. namespace WPFNavigation
  16. {
  17. public class NavigationPanel : StackPanel
  18. {
  19. public event EventHandler AnimationComplte;
  20. private static double COUNT_OF_PAGE;
  21. private TranslateTransform NavigationPanelTranslateTransform;
  22. private static readonly TimeSpan DURATION = TimeSpan.FromMilliseconds(250);
  23. public NavigationPanel():base()
  24. {
  25. this.Orientation = Orientation.Horizontal;
  26. NavigationPanelTranslateTransform = new TranslateTransform();
  27. this.Loaded += new RoutedEventHandler(NavigationPanel_Loaded);
  28. }
  29. void NavigationPanel_Loaded(object sender, RoutedEventArgs e)
  30. {
  31. COUNT_OF_PAGE = this.Children.Count;
  32. CurrentIndex = 0;
  33. foreach (FrameworkElement fe in this.Children)
  34. {
  35. fe.RenderTransform = NavigationPanelTranslateTransform;
  36. }
  37. }
  38. public void Next()
  39. {
  40. AnimationChildren(true);
  41. }
  42. public void Previous()
  43. {
  44. AnimationChildren(false);
  45. }
  46. private bool ValidateNext()
  47. {
  48. return CurrentIndex < (COUNT_OF_PAGE - 1) && CurrentIndex >= 0;
  49. }
  50. private bool ValidatePrevious()
  51. {
  52. return CurrentIndex <= (COUNT_OF_PAGE - 1) && CurrentIndex > 0;
  53. }
  54. private bool ValidateCurrentIndex()
  55. {
  56. if (CurrentIndex > -1 && CurrentIndex < this.Children.Count)
  57. {
  58. return true;
  59. }
  60. return false;
  61. }
  62. private  void AnimationChildren(bool forward)
  63. {
  64. double currentTranX = NavigationPanelTranslateTransform.X;
  65. double nextTranX = currentTranX;
  66. if (forward)
  67. {
  68. if (ValidateCurrentIndex())
  69. {
  70. nextTranX -= (this.Children[CurrentIndex] as FrameworkElement).ActualWidth;
  71. }
  72. }
  73. else
  74. {
  75. if (ValidateCurrentIndex())
  76. {
  77. nextTranX += (this.Children[CurrentIndex] as FrameworkElement).ActualWidth;
  78. }
  79. }
  80. DoubleAnimation da = new DoubleAnimation(currentTranX, nextTranX, DURATION);
  81. da.Completed += (o1, e1) =>
  82. {
  83. CurrentIndex += forward ? 1 : -1;
  84. if (AnimationComplte != null)
  85. {
  86. AnimationComplte(this, e1);
  87. }
  88. };
  89. NavigationPanelTranslateTransform.BeginAnimation(TranslateTransform.XProperty, da);
  90. }
  91. #region CurrentIndex
  92. /// <summary>
  93. /// The <see cref="CurrentIndex" /> dependency property's name.
  94. /// </summary>
  95. public const string CurrentIndexPropertyName = "CurrentIndex";
  96. /// <summary>
  97. /// Gets or sets the value of the <see cref="CurrentIndex" />
  98. /// property. This is a dependency property.
  99. /// </summary>
  100. public int CurrentIndex
  101. {
  102. get
  103. {
  104. return (int)GetValue(CurrentIndexProperty);
  105. }
  106. set
  107. {
  108. SetValue(CurrentIndexProperty, value);
  109. }
  110. }
  111. /// <summary>
  112. /// Identifies the <see cref="CurrentIndex" /> dependency property.
  113. /// </summary>
  114. public static readonly DependencyProperty CurrentIndexProperty = DependencyProperty.Register(
  115. CurrentIndexPropertyName,
  116. typeof(int),
  117. typeof(NavigationPanel),
  118. new UIPropertyMetadata(-1, OnCurrentIndexChanged));
  119. private static void OnCurrentIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  120. {
  121. (d as NavigationPanel).OnCurrentIndexChanged((int)e.OldValue, (int)e.NewValue);
  122. }
  123. protected virtual void OnCurrentIndexChanged(int oldIndex, int newIndex)
  124. {
  125. NextIsValid = ValidateNext();
  126. PreviousIsValid = ValidatePrevious();
  127. }
  128. #endregion // CurrentIndex
  129. #region NextIsValid
  130. /// <summary>
  131. /// The <see cref="NextIsValid" /> dependency property's name.
  132. /// </summary>
  133. public const string NextIsValidPropertyName = "NextIsValid";
  134. /// <summary>
  135. /// Gets or sets the value of the <see cref="NextIsValid" />
  136. /// property. This is a dependency property.
  137. /// </summary>
  138. public bool NextIsValid
  139. {
  140. get
  141. {
  142. return (bool)GetValue(NextIsValidProperty);
  143. }
  144. set
  145. {
  146. SetValue(NextIsValidProperty, value);
  147. }
  148. }
  149. /// <summary>
  150. /// Identifies the <see cref="NextIsValid" /> dependency property.
  151. /// </summary>
  152. public static readonly DependencyProperty NextIsValidProperty = DependencyProperty.Register(
  153. NextIsValidPropertyName,
  154. typeof(bool),
  155. typeof(NavigationPanel),
  156. new UIPropertyMetadata(false));
  157. #endregion // NextIsValid
  158. #region PreviousIsValid
  159. /// <summary>
  160. /// The <see cref="PreviousIsValid" /> dependency property's name.
  161. /// </summary>
  162. public const string PreviousIsValidPropertyName = "PreviousIsValid";
  163. /// <summary>
  164. /// Gets or sets the value of the <see cref="PreviousIsValid" />
  165. /// property. This is a dependency property.
  166. /// </summary>
  167. public bool PreviousIsValid
  168. {
  169. get
  170. {
  171. return (bool)GetValue(PreviousIsValidProperty);
  172. }
  173. set
  174. {
  175. SetValue(PreviousIsValidProperty, value);
  176. }
  177. }
  178. /// <summary>
  179. /// Identifies the <see cref="PreviousIsValid" /> dependency property.
  180. /// </summary>
  181. public static readonly DependencyProperty PreviousIsValidProperty = DependencyProperty.Register(
  182. PreviousIsValidPropertyName,
  183. typeof(bool),
  184. typeof(NavigationPanel),
  185. new UIPropertyMetadata(false));
  186. #endregion // PreviousIsValid
  187. }
  188. }

WPF如何实现类似iPhone界面切换的效果(转载)的更多相关文章

  1. 编写最简单的 iPhone 界面切换应用

    编写最简单的 iPhone 界面切换应用   以下是在iOS中最简单的界面切换示例.使用了多个Controller,并演示Controller之间在切换界面时的代码处理. 实现的应用界面: 首先,创建 ...

  2. Xcode界面切换动画效果

    CATransition *animation = [CATransition animation]; [animation setDuration:0.2f]; [animation setTimi ...

  3. WPF触控程序开发&lpar;三&rpar;——类似IPhone相册的反弹效果

    用过IPhone的都知道,IPhone相册里,当图片放大到一定程度后,手指一放,会自动缩回,移动图片超出边框后手指一放,图片也会自动缩回,整个过程非常和谐.自然.精确,那么WPF能否做到呢,答案是肯定 ...

  4. 巧妙利用jQuery和PHP打造类似360安全卫士防火墙功能开关&lpar;类似iphone界面&rpar;效果

    安全卫士防火墙开启关闭的开关,可以将此功能应用在产品功能的开启和关闭功能上. 准备工作为了更好的演示本例,我们需要一个数据表,记录需要的功能说明及开启状态,表结构如下: CREATE TABLE `p ...

  5. 不用图片,纯Css3实现超酷的类似iphone的玻璃气泡效果

    最近在一个私活做手机项目时候,需要实现一个类似ios 6中短信那样的气泡效果. 这里分享下实现心得,希望能给大家一点启发. 首先分析下iphone的气泡效果有一下特点 1. 四面圆角 2. 界面上向下 ...

  6. WPF点击不同界面上的按钮实现界面切换

    原文:WPF点击不同界面上的按钮实现界面切换 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_29844879/article/details/ ...

  7. Html5 Egret游戏开发 成语大挑战(五)界面切换和数据处理

    经过前面的制作,使用Egret的Wing很快完成了开始界面和选关卡界面,下面通常来说就是游戏界面,但此时界面切换和关卡数据还没有准备好,这次讲解界面的切换和关卡数据的解析.前面多次修改了Main.ts ...

  8. C&num;实现多国语言的界面切换

    在PictureStudio中,我需要实现多国语言的界面切换,而且切换各种语言版本的时候希望程序是动态的加载语言,不希望切换语言后重新启动程序. 实现这样的功能可以有很愚蠢的方法,比如说你可以在程序中 ...

  9. Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(下)

    原文:Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(下) 接着上篇... 接下去,将一步步演示如果创建当点击checkBox后,其中的按钮由左边滑动到右边,表示处于 ...

随机推荐

  1. 在 JS 中使用 fetch 更加高效地进行网络请求

    在前端快速发展地过程中,为了契合更好的设计模式,产生了 fetch 框架,此文将简要介绍下 fetch 的基本使用. 我的源博客地址:http://blog.parryqiu.com/2016/03/ ...

  2. Apache 配置多端口

    Apache 配置多端口,主要是以下步骤 1. 如果电脑是64位的,官网上下载WampServe,装的过程中如果出现msvcp110.dll丢失的话,解决办法如下: 1.1 首先是打开浏览器,在浏览器 ...

  3. faker image

    $faker->image http://placehold.it http://placekitten.com/g/200/300 带文字 https://placeholdit.imgix. ...

  4. SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-004- 处理上传文件

    一.用 MultipartFile 1.在html中设置<form enctype="multipart/form-data">及<input type=&quo ...

  5. c&num;后台验证

    #region 后台验证 panda /// 验证电话号码的主要代码如下: public bool IsTelephone(string str_telephone) { return System. ...

  6. 数据挖掘之clara算法原理及实例&lpar;代码中有bug&rpar;

    继上两篇文章介绍聚类中基于划分思想的k-means算法和k-mediod算法 本文将继续介绍另外一种基于划分思想的k-mediod算法-----clara算法 clara算法可以说是对k-mediod ...

  7. 39&period;Linux应用调试-strace命令

    1.strace简介 strace常用来跟踪进程执行时的系统调用和所接收的信号.通过strace可以知道应用程序打开了哪些文件,以及读写了什么内容,包括消耗的时间以及返回值等 2.安装strace命令 ...

  8. java应用的优化【转】

    XX银行网银系统是一套全新的对公业务渠道类系统,经过两年的建设,将逐步对外提供服务. 该系统融合了原来多个对公渠道系统,并发量是以前多个系统之和,吞吐量要求将大幅上升.为了使广大对公客户使用系统时获得 ...

  9. HTML5的placeHolder在IE9下workaround引发的Bug(按下葫芦起了瓢)

    详见*的:Simple jQuery form Validation: Checking for empty .val() failing in ie9 due to plac ...

  10. ReactiveX 学习笔记(15)使用 Rx&period;NET &plus; Json&period;NET 调用 REST API

    JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...