还是在持续的开发一款Windows10的应用中,除了上篇博客讲讲我在Windows10(uwp)开发中遇到的一些坑,其实还有很多不完善的地方,比如__(UIElement.Foreground).(GradientBrush.GradientStops)[1].(GradientStop.Offset)__这种设置无法生效,还有RelativePanel内的元素不能自动的适应大小,要去手动控制宽高度,以及窗口在靠边的时候一些尺寸上的错误等等。虽然是WPF技术之后的延续,但是很多地方还是要小心仔细的处理,很多开发上的注意力也是在考虑如何解决以及如何更好的解决这些问题。 在开发的过程中其实也写了一些控件,比如自定义的文本框(TextBlock已经变成了密封类),下拉刷新以及加载更多的ListView.比较简单,而且功能上比较完善的可以拿出来用的目前大概只有一个侧滑.当然,它依然有一个致命的缺陷,这个稍后再表.

侧滑应该是一个比较简单的东西,配合Manipulation一系列的事件,获取偏移量以及偏移速度就能轻松实现.当然,这套api和其他平台比,真的还是有很多的限制的.微软在底层吃掉了过多的事件,希望能更加开放点.

看下演示视频:

http://v.youku.com/v_show/id_XMTMyNTAxMDQ2MA==.html?from=y1.7-1.2

先来说下界面上的布局.

<Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="20"/>
        </Grid.ColumnDefinitions>
        <Rectangle Fill="Green" x:Name="DismissLayout" Tapped="DismissLayout_Tapped" Visibility="Collapsed" Grid.Column="0"/>
        <Rectangle Fill="Red" Grid.Column="1" ManipulationCompleted="ManipulationCompleted"  x:Name="ManipulationLayout"
        ManipulationDelta="ManipulationDelta" 
        ManipulationMode="TranslateX">
            <Rectangle.RenderTransform>
                <CompositeTransform/>
            </Rectangle.RenderTransform>
        </Rectangle>
    </Grid>
    <Grid Background="White" HorizontalAlignment="Right"  Margin="0,0,-300,0" Width="300"
        x:Name="Panel"
        ManipulationCompleted="ManipulationCompleted" 
        ManipulationDelta="ManipulationDelta" 
        ManipulationMode="TranslateX">
        <Grid.RenderTransform>
            <CompositeTransform/>
        </Grid.RenderTransform>
        <ListBox Name="listbox" Background="Yellow">
            <ListBoxItem Content="123"/>
            ...
            <ListBoxItem Content="123"/>
        </ListBox>
    </Grid>
</Grid>

界面上的布局大概是这样的:Grid的右侧是一个20像素的Rectangle,用来接收从侧边进入的手势.然后在Grid之外,是我们需要划入的Panel,然后DismissLayout是用来接收我们在我们滑动区域之外的内容,可以在我们点击的时候,隐藏掉我们的Panel.

后台的代码

public MainPage()
{
    this.InitializeComponent();
    //如果是其他的带有滚动的控件,要禁用滚动,手机版才能使用。PC版无影响
    ScrollViewer.SetVerticalScrollMode(listbox, ScrollMode.Disabled);
}

private new void ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
    var x = e.Velocities.Linear.X;
    if (x <= -0.1)
    {
        OpenPanel();
    }
    else if (x > -0.1 && x < 0.1)
    {
        if (Math.Abs((Panel.RenderTransform as CompositeTransform).TranslateX) > 150)
        {
            OpenPanel();
        }
        else
        {
            ClosePanel();
        }

    }
    else
    {
        ClosePanel();
    }
}

private new void ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var x = (Panel.RenderTransform as CompositeTransform).TranslateX + e.Delta.Translation.X;
    if (x < -300)
    {
        x = -300;
    }
    (Panel.RenderTransform as CompositeTransform).TranslateX = x;
    (ManipulationLayout.RenderTransform as CompositeTransform).TranslateX = x;
}

private void DismissLayout_Tapped(object sender, TappedRoutedEventArgs e)
{
    ClosePanel();
}

private void OpenPanel()
{
    OpenView.Begin();
    DismissLayout.Visibility = Visibility.Visible;
}

private void ClosePanel()
{
    CloseView.Begin();
    DismissLayout.Visibility = Visibility.Collapsed;
}

后台的代码只是处理各种情况下的偏移量,其中在构造函数内禁用了滚动,这就是这个侧滑控件致命的地方,Panel里面如果存在ListView或者ListBox之类的控件的时候,它的手势事件会被吃掉.奇怪的是手机端是会被吃掉,但是PC端不会.希望手机版在正式版的时候,也可以像PC版一样操作.

为了比较好的显示效果,也可以加入一些动画.

<Storyboard x:Name="OpenView">
    <DoubleAnimation Duration="0:0:0.2" To="-300" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ManipulationLayout" d:IsOptimized="True">
        <DoubleAnimation.EasingFunction>
            <ExponentialEase EasingMode="EaseIn" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
    <DoubleAnimation Duration="0:0:0.2" To="-300" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="Panel" d:IsOptimized="True">
        <DoubleAnimation.EasingFunction>
            <ExponentialEase EasingMode="EaseIn" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
</Storyboard>
<Storyboard x:Name="CloseView">
    <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ManipulationLayout" d:IsOptimized="True">
        <DoubleAnimation.EasingFunction>
            <ExponentialEase EasingMode="EaseOut" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
    <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="Panel" d:IsOptimized="True">
        <DoubleAnimation.EasingFunction>
            <ExponentialEase EasingMode="EaseOut" />
        </DoubleAnimation.EasingFunction>
    </DoubleAnimation>
</Storyboard>

只要Panel里不是什么ListView之类的控件,可以直接放入代码中使用.

实际的使用效果:

http://v.youku.com/v_show/id_XMTMyNTAxMDkyOA==.html

源码下载:http://files.cnblogs.com/files/youngytj/SwipeView.zip