WP8.1 侧边滑动Item
效果图
我看ios 和安卓上有好多类似的Item的效果,UWP上有微软官方的库,其中也有类似得效果,看样子WP8.1没有啊,顺便我的程序也是需要,我也就仿了一个。
具体思路是: 触摸控制GRId在CANvas的相对位置。滑动这个Item时候,其他已经滑动完成的ITEM关闭。只能有一个打开。
实现这个效果,至少需要以下知识点:
Canvsa基础知识
触控基础知识
ObservableCollection<T>基本使用
INotifyPropertyChanged接口基本使用
咱也不罗嗦 开始
先上xaml代码
<ListView x:Name="listView" SelectionChanged="listView_SelectionChanged" > <ListView.ItemTemplate> <DataTemplate> <!--几个关键触控设置--> <!--ManipulationCompleted="X1_ManipulationCompleted" ManipulationDelta="X1_ManipulationDelta" ManipulationStarted="X1_ManipulationStarted" ManipulationMode="TranslateX,System" --> <Grid ManipulationCompleted="X1_ManipulationCompleted" ManipulationDelta="X1_ManipulationDelta" ManipulationStarted="X1_ManipulationStarted" ManipulationMode="TranslateX,System" Height="139" Width="{Binding ItemWidth}"> <!--关键的底板,Canvsa--> <Canvas x:Name="C1"> <!--对其主体Gird的Canvsa.Left绑定--> <!--Canvas.Left="{Binding CanvsaLeft, Mode=TwoWay}"--> <Grid Canvas.Left="{Binding CanvsaLeft, Mode=TwoWay}" x:Name="G1" Height="139" Width="580"> <!--分块,一块是屏幕的显示,一个在隐藏着中--> <!--屏幕这一块,可以用Binding绑定,另一个随意了 看心情,不过这也和Canvsa.left大小也有关心--> <Grid.ColumnDefinitions> <ColumnDefinition Width="450*"/> <ColumnDefinition Width="130*"/> </Grid.ColumnDefinitions> <Grid> <Grid.RowDefinitions> <RowDefinition Height="73*"/> <RowDefinition Height="70*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="28*"/> <ColumnDefinition Width="47*"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding ImageName}" FontSize="28" Grid.ColumnSpan="2" Margin="168,10,0,0.333"/> <TextBlock Text="{Binding ImageAge}" FontSize="28" Grid.ColumnSpan="2" Grid.Row="1" Margin="168,10,0,0.333"/> <Image Source="TOPImage/ops.png" Grid.Column="0" Grid.RowSpan="2" Margin="3"/> </Grid> <Grid Grid.Column="1" > <Border BorderThickness="1,0,0,0"> <Border.BorderBrush> <SolidColorBrush Color="Black"/> </Border.BorderBrush> <Image Source="IcoImage/del.png" /> </Border> </Grid> </Grid> </Canvas> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView>
ObservableCollection<T>+INotifyPropertyChanged接口的代码:
public class ReadDataList { private ObservableCollection<DataList> setData = new ObservableCollection<DataList>(); public ObservableCollection<DataList> GetData() { return setData; } } public class DataList : INotifyPropertyChanged//变化接口,通知UI { private double Nub; public string ImageName { get; set; } public string ImageAge { get; set; } public double ItemWidth //绑定手机具体的宽度 { get { return Window.Current.Bounds.Width; } } public ImageSource imageSourec { get; set; } public double CanvsaLeft //滑动的基础,就是对Canvsa的相对位置的处理 { get { return Nub; } set { Nub = value; OnChanged(new PropertyChangedEventArgs("CanvsaLeft")); } } public int ItemCount { get; set; } public event PropertyChangedEventHandler PropertyChanged; protected void OnChanged(PropertyChangedEventArgs arg)//具体方法 { if (PropertyChanged != null) { PropertyChanged(this, arg); } } }
对屏幕滑动的处理代码:
private void X1_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)//手在屏幕移动方法 { P2 = e.Cumulative.Translation; //触摸点结束位置 if (P2.X < P1.X && (Canvas.GetLeft(G1) != -130))//X轴的判断,向左滑动,且Item的初始Canvsa的相对位置不能大于-130 { if (Canvas.GetLeft(G1) >= -130) { Canvas.SetLeft(G1, P2.X++); } } if (P2.X < P1.X)//滑动结束或者滑动中 { if (Canvas.GetLeft(G1) < -130) { Canvas.SetLeft(G1, -130); } } if (P2.X > P1.X)//向右滑动,返回ITEM 一下子回去 这块的代码不是很好 带我优化优化把 { if (Canvas.GetLeft(G1) < 1) { Canvas.SetLeft(G1, Canvas.GetLeft(G1) + P2.X); } } if (P2.X > P1.X)//向右滑动,返回Item 滑动中 { if (Canvas.GetLeft(G1) > 0) { Canvas.SetLeft(G1, 0); } } e.Handled = true;//结束这段代码 P1.X = 0;//清空 P2.X = 0;//清空 } private void X1_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e) //触摸开始 { G1 = ((Grid)sender).FindName("G1") as Grid;//确定触摸事件源头(具体Item) P1 = e.Position;//触摸点的起点位置 } private void X1_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)//手离开屏幕 { if (Canvas.GetLeft(G1) > -65)//判断向左滑动途中手是否离开屏幕,离开屏幕时Item的位置 以此判断 小于一般 回到0 大于一半到结束位置 { Canvas.SetLeft(G1, 0); } if ((Canvas.GetLeft(G1) < -65)) { Canvas.SetLeft(G1, -130); OneItemData = (e.OriginalSource as FrameworkElement).DataContext as DataList;//确定滑动的Item SetCanvas(OneItemData);//判断其他Item是否打开的方法 } } void SetCanvas(object sender)//判断再滑动Item时是否已经有其他Item已经滑动完成,有就关闭。 { var data= sender as DataList; //现在正在滑动的ITEM for (int i = 0; GetAllData.Count> i; i++)//datalist全部的集合 { if (GetAllData[i].CanvsaLeft == -130&&GetAllData[i].ItemCount!=data.ItemCount)//判断其中元素的CANvas元素是否位-130,同时确保这个元素不是正在滑动的元素 { GetAllData[i].CanvsaLeft = 0;//是就将Canvas.left的相对位置=0 } } }