Introduction

The ListView displays data stacked vertically in a single column. It is often used to show an ordered list of items with the possibility to scroll vertically only.

But, what if you want to display data vertically with horizontal swipe enabled on each item of your ListView (see image below)?

This wiki explains step by step how to make ListView scroll vertically with horizontal swipe enabled in Universal Windows App (C# and XAML) on Visual Studio 2017.

 

Step 1: Create a new Universal Windows project (C# and XAML)

  • Open Visual Studio 2017.
  •  Create a new Universal Windows project (C# and XAML): ListViewScrollAndSwipe

Step 2: Create models

  • Create in the project ListViewScrollAndSwipe, a new folder: Models
  • In the Models folder, create two classes: Course.cs and Training.cs
  •  Insert the following code in Course.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace ListViewScrollAndSwipe.Models
{
 public class Course
 {
 public int Id { get; set; }
  
 public string Name { get; set; }
  
 public int Progress { get; set; }
 }
}

  • Insert the following code in Training.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace ListViewScrollAndSwipe.Models
{
 public class Training
 {
  
 public string Category { get; set; }
  
 public List<Course> Courses { get; set; }
  
 }
}

Step 3: Create the user interface

  • Open the file MainPage.xaml. and insert the following code:
<Page x:Class=" ListViewScrollAndSwipe.MainPage"
 xmlns:local="using:ListViewScrollAndSwipe "
 xmlns:models="using:ListViewScrollAndSwipe.Models"
 mc:Ignorable="d">
  
 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto" />
 <RowDefinition Height="*" />
 </Grid.RowDefinitions>
  
 <!--TITLE-->
 <TextBlock Text="Trainings"
 Style="{StaticResource TitleTextBlockStyle}"
 Margin="20" />
   
 <!--LISTVIEW-->
 <ListView Margin="20"
 x:Name="LVTrainings"
 Grid.Row="1"
 VerticalAlignment="Top"
 SelectionMode="None"
 IsItemClickEnabled="True">
 <ListView.ItemTemplate>
 <DataTemplate x:DataType="models:Training">
 <Grid>
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto" />
 <RowDefinition Height="*" />
 </Grid.RowDefinitions>
 <Grid Background="WhiteSmoke">
 <TextBlock Text="{x:Bind Category}"
 Margin="10"
 Style="{StaticResource SubtitleTextBlockStyle}"
 Foreground="#0099CC" />
 </Grid>
  
 <!--FLIPVIEW-->
 <FlipView ItemsSource="{x:Bind Courses}"
 Grid.Row="1"
 Background="#0099CC"
 Tapped="FlipView_Tapped">
 <FlipView.ItemTemplate>
 <DataTemplate x:DataType="models::Course">
 <Grid>
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto" />
 <RowDefinition Height="*" />
 </Grid.RowDefinitions>
 <TextBlock Text="{x:Bind Name}"
 TextTrimming="None"
 TextWrapping="WrapWholeWords"
 Margin="10"
 Foreground="White"
 Style="{StaticResource SubtitleTextBlockStyle}" />
  
 <ProgressBar Margin="10"
 Minimum="0"
 Maximum="100"
 Value="{x:Bind Progress}"
 BorderBrush="White"
 BorderThickness="1"
 Background="Transparent"
 Foreground="White"
 Grid.Row="1"
 VerticalAlignment="Bottom" />
 </Grid>
 </DataTemplate>
 </FlipView.ItemTemplate>
 </FlipView>
 </Grid>
 </DataTemplate>
 </ListView.ItemTemplate>
 <ListView.ItemContainerStyle>
 <Style TargetType="ListViewItem">
 <Setter Property="Padding"
 Value="10" />
 <Setter Property="Width"
 Value="300" />
  
 <Setter Property="Height"
 Value="300" />
 </Style>
 </ListView.ItemContainerStyle>
 </ListView>
 </Grid>
</Page>

As you can see, the horizontal swipe enabled is handled by the FlipView control.

In this code : 

<FlipView ItemsSource="{x:Bind Courses}"
 Grid.Row="1"
 Background="#0099CC"
 Tapped="FlipView_Tapped">
 <FlipView.ItemTemplate>
 <DataTemplate x:DataType="models::Course">
 <Grid>
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto" />
 <RowDefinition Height="*" />
 </Grid.RowDefinitions>
 <TextBlock Text="{x:Bind Name}"
 TextTrimming="None"
 TextWrapping="WrapWholeWords"
 Margin="10"
 Foreground="White"
 Style="{StaticResource SubtitleTextBlockStyle}" />
  
 <ProgressBar Margin="10"
 Minimum="0"
 Maximum="100"
 Value="{x:Bind Progress}"
 BorderBrush="White"
 BorderThickness="1"
 Background="Transparent"
 Foreground="White"
 Grid.Row="1"
 VerticalAlignment="Bottom" />
 </Grid>
 </DataTemplate>
 </FlipView.ItemTemplate>
 </FlipView>

The FlipView control allows user to swipe horizontally many items. That's why I use for displaying the data will be swiped.

In our case it's a list of Courses as it's defined in the x:DataType of the DataTemplate.

Step 4: Populate the datas in the ListView

  • Open the file MainPage.xaml.cs and insert the OnNavigatedTo method with the following code:
protected override void OnNavigatedTo(NavigationEventArgs e)
 {
 base.OnNavigatedTo(e);
  
 List<Training> LstTrainings = new List<Training>()
 {
  
 new Training
 {
 Category="C# / XAML",
 Courses=new List<Course>()
 {
 new Course
 {
 Id=1,
 Name="Inking and InkCanvas",
 Progress=20
   
 },
  
 new Course
 {
 Id=2,
 Name="Speech Recognition and Cortana Integration",
 Progress=60
 },
  
 new Course
 {
 Id=3,
 Name="MS Build 2017 Revisited : Azure",
 Progress=80
  
 }
  
  
 },
  
 },
  
 new Training
 {
  
 Category="Visual Studio",
 Courses=new List<Course>()
 {
 new Course
 {
 Id=4,
 Name="Top 10 JavaScript Questions",
 Progress=75
 },
  
 new Course
 {
 Id=5,
 Name="What's New and Improved in Visual Studio 2017",
 Progress=10
 },
  
 new Course
 {
 Id=6,
 Name="ASP.NET Core",
 Progress=45
 }
 }
 },
 };
  
 LVTrainings.ItemsSource = LstTrainings;
  
 }

Step 5: Handle the FlipView Tapped event

As we saw in the step 3, we use FlipView to display items in the swipe. But how to know which element in the FlipView is selected?

To do that, we will use the Tapped event of the FlipView

  • Open the MainPage.xaml.cs and insert the code below:
private async void FlipView_Tapped(object sender, TappedRoutedEventArgs e)
 {
 ContentPresenter contentPresenter = e.OriginalSource as ContentPresenter;
 Course course = contentPresenter.Content as Course;
  
 if (course != null)
 {
  
 ContentDialog contentDialog = new ContentDialog()
 {
 Title = "ListView Scroll And Swipe",
 Content = String.Format("You've selected this course : {0}", course.Name),
 PrimaryButtonText = "Ok"
 };
  
 ContentDialogResult result = await contentDialog.ShowAsync();
  
 }
 }

The FlipView_Tapped event contains two parameters: object (sender) and TappedRoutedEventArgs (e), the e.OriginalSource can be useful for determining the element that first raised the event. In our case, the e.OrginalSource returns a ContentPresenter

The ContentPresenter contains the Content property which allow to get his content.

As we know the FlipView contains a list of Courses so we are going to convert the Content of the ContentPresenter in Course type.

This code allows it: 

ContentPresenter contentPresenter = e.OriginalSource as ContentPresenter;
 Course course = contentPresenter.Content as Course;

To display the selected course, I use ContentDialog :


ContentDialog contentDialog = new ContentDialog()
 {
 Title = "ListView Scroll And Swipe",
 Content = String.Format("You've selected this course : {0}", course.Name),
 PrimaryButtonText = "Ok"
 };
   
 ContentDialogResult result = await contentDialog.ShowAsync();


Step 6: Run the project

Build and Run the project ListViewScrollAndSwipe

 

Conclusion

This wiki explained how to make ListView scroll vertically with horizontal swipe in Universal Windows App

See Also