方案1: 利用 Panorama或者 pivotpage
1. 重写panorama page, 使其达到全屏
public class PanoramaFullScreen : Panorama {
protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
{
availableSize.Width += 48;
return base.MeasureOverride(availableSize);
}
}
2. 去掉 title 和 header,调整好margin
<phone:PanoramaItem>
<Grid Canvas.ZIndex="-1" Margin="-66,-40,-55,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="591">
<Image Stretch="Fill" Source="/Images/screen1.jpg" VerticalAlignment ="Stretch"
HorizontalAlignment="Stretch" Margin="54,0,54,0"/>
</Grid>
</phone:PanoramaItem>
3. 在codebehind 中控制页面跳转
private TouchPoint first;
private const int DetectRightGesture = 20;
private int startIndex = 0;
private readonly int endIndex;
public WhatsNewView()
{
InitializeComponent();
endIndex = MyStartScreen.Items.Count - 1;
MyStartScreen.IsHitTestVisible = false;
MyStartScreen.IsEnabled = false;
Touch.FrameReported += Touch_FrameReported;
TouchPanel.EnabledGestures = GestureType.HorizontalDrag;
}
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
try
{
TouchPoint mainTouch = e.GetPrimaryTouchPoint(this);
if (mainTouch.Action == TouchAction.Down)
first = mainTouch;
else if (mainTouch.Action == TouchAction.Up && TouchPanel.IsGestureAvailable)
{
if (mainTouch.Position.X - first.Position.X < -DetectRightGesture)
{
if (startIndex < endIndex)
{
MyStartScreen.SlideToPage(startIndex + 1, SlideTransitionMode.SlideLeftFadeOut);
startIndex++;
}
else
{
NavigateToNextPage();
}
}
else if (mainTouch.Position.X - first.Position.X > DetectRightGesture)
{
if (startIndex > 0)
{
MyStartScreen.SlideToPage(startIndex - 1, SlideTransitionMode.SlideRightFadeOut);
startIndex--;
}
}
}
}
catch
{
}
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
NavigateToNextPage();
}
private void NavigateToNextPage()
{
NavigationService.Navigate(new Uri("/Views/LoginPage.xaml", UriKind.Relative));
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
while (NavigationService.BackStack.Any())
{
NavigationService.RemoveBackEntry();
}
}
4. 补充: 拓展panorama 方法,使其跳转附带动画
public static void SlideToPage(this Panorama self, int item, SlideTransitionMode slideMode)
{
var slideTransition = new SlideTransition { };
slideTransition.Mode = slideMode;
ITransition transition = slideTransition.GetTransition(self);
transition.Completed += delegate
{
self.DefaultItem = self.Items[item];
transition.Stop();
};
transition.Begin();
}
不足:
SlideTransitionMode SlideTransitionMode支持动画有限,一般达不到预期效果
方案2:
将所有图片水平排列,根据手势通过左右偏移来控制显示
<Canvas>
<StackPanel x:Name="Slider"
Canvas.Left="0"
Orientation="Horizontal">
<Image Source="/Images/screen1.jpg"
Stretch ="UniformToFill"/>
<Image Source="/Images/screen2.jpg"
Stretch ="UniformToFill" />
<Image Source="/Images/screen3.jpg"
Stretch ="UniformToFill" />
</StackPanel>
</Canvas>
一般来说,最后一页面中的按钮和前面不同,可以通过 SlidePageIndex 来区分。先将其声明为依赖属性,在view中通过converter来控制是否显示
public static readonly DependencyProperty SlidePageIndexProperty =
DependencyProperty.Register("SlidePageIndex", typeof(int), typeof(StartScreenView), null);
public int SlidePageIndex
{
get { return (int)GetValue(SlidePageIndexProperty); }
set { SetValue(SlidePageIndexProperty, value); }
}
偏移量根据不同设备决定
_uniformImageWidth = (int)Application.Current.Host.Content.ActualWidth;
手势控制
Touch.FrameReported += Touch_FrameReported;
TouchPanel.EnabledGestures = GestureType.HorizontalDrag;
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
try
{
TouchPoint mainTouch = e.GetPrimaryTouchPoint(this);
if (mainTouch.Action == TouchAction.Down)
first = mainTouch;
else if (mainTouch.Action == TouchAction.Up && TouchPanel.IsGestureAvailable)
{
if (mainTouch.Position.X - first.Position.X < -DetectRightGesture)
{
if (SlidePageIndex == MaxSlidePageCount - 1)
{
NavigateToLoginPage();
}
SlidePageIndex++;
Slide();
}
else if (mainTouch.Position.X - first.Position.X > DetectRightGesture)
{
if (SlidePageIndex == 0) return;
SlidePageIndex--;
Slide();
}
}
}
catch
{
}
}
滑动逻辑
private void Slide()
{
var storyboard = new Storyboard();
var ani = new DoubleAnimation();
ani.To = SlidePageIndex * -_uniformImageWidth;
ani.Duration = TimeSpan.FromSeconds(1.0f);
ani.EasingFunction = new ElasticEase() { EasingMode = EasingMode.EaseInOut, Oscillations = 0 };
Storyboard.SetTarget(ani, this.Slider);
Storyboard.SetTargetProperty(ani, new PropertyPath("(Canvas.Left)"));
storyboard.Children.Add(ani);
storyboard.Begin();
}
此页面不可以通过back键导航
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
while (NavigationService.BackStack.Any())
{
NavigationService.RemoveBackEntry();
}
}