ListView/GridView DataBinding, Grouping, Sorting and Semantic Zoom in Windows Phone 8.1

This article describes about data binding, grouping, sorting and semantic zoom features of ListView/GridView in windows phone 8.1 (winrt).

Create a universal app project; by creating a Universal app project, you will get two projects, project for windows store and project for Windows Phone by sharing the shared project.
Note: Make sure you install VS 2013 with Update 2 for creating a Universal app project.

Create a model class with properties as below
public class Task
{
public string TaskName { get; set; }

public DateTime CreatedDate { get; set; }
}

Create a mock data class for preparing the mock data which will be used for data binding of ListView/GridView
public static class MockData
{
public static List<Task> GetTasksForGrouping()
{
var tasks = new List<Task>();
tasks.Add(new Task { TaskName = "Task Item1", CreatedDate = DateTime.Today });
tasks.Add(new Task { TaskName = "Task Item2", CreatedDate = DateTime.Today.AddDays(2) });
tasks.Add(new Task { TaskName = "Task Item3", CreatedDate = DateTime.Today.AddDays(1) });
tasks.Add(new Task { TaskName = "Task Item4", CreatedDate = DateTime.Today.AddDays(1) });
tasks.Add(new Task { TaskName = "Task Item5", CreatedDate = DateTime.Today.AddDays(2) });
tasks.Add(new Task { TaskName = "Task Item6", CreatedDate = DateTime.Today.AddDays(4) });
tasks.Add(new Task { TaskName = "Task Item7", CreatedDate = DateTime.Today.AddDays(5) });
tasks.Add(new Task { TaskName = "Task Item8", CreatedDate = DateTime.Today.AddDays(1) });
tasks.Add(new Task { TaskName = "Task Item9", CreatedDate = DateTime.Today.AddDays(2) });
tasks.Add(new Task { TaskName = "Task Item10", CreatedDate = DateTime.Today.AddDays(2) });
tasks.Add(new Task { TaskName = "Task Item11", CreatedDate = DateTime.Today.AddDays(2) });
tasks.Add(new Task { TaskName = "Task Item12", CreatedDate = DateTime.Today.AddDays(4) });
tasks.Add(new Task { TaskName = "Task Item13", CreatedDate = DateTime.Today.AddDays(4) });
tasks.Add(new Task { TaskName = "Task Item14", CreatedDate = DateTime.Today.AddDays(4) });
return tasks;
}

Create a ViewModel class with default constructor and properties as below.
public class ListViewGroupViewModel : ViewModelBase
{
private IOrderedEnumerable<IGrouping<DateTime, Task>> groupTasks;
public ListViewGroupViewModel()
{
}

public IOrderedEnumerable<IGrouping<DateTime, Task>> GroupTasks
{
get
{
return this.groupTasks;
}

set
{
this.groupTasks = value;
this.RaisePropertyChanged(() => this.GroupTasks);
}
}
}

Here, using the collection IOrderedEnumerable<IGrouping<DateTime, Task>> for grouping and sorting.
Now, get the mock data, then group and sort using LINQ as below. Here, grouping the collection of Tasks by DateTime.
private void GetTasks()
{
var tasks = MockData.GetTasksForGrouping();
this.GroupTasks = from act in tasks
group act by act.CreatedDate
into grp
orderby grp.Key ascending
select grp;
}

If we use MVVM design pattern, we should create a ViewModelLocator class which will be used as intermediate layer for resolving IOC and binding the viewmodel as DataContext to view.
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

SimpleIoc.Default.Register<ListViewGroupViewModel>();
}

public ListViewGroupViewModel ListViewGroupViewModel
{
get
{
return ServiceLocator.Current.GetInstance<ListViewGroupViewModel>();
}
}
}

Add this class as a resource in App.xaml file.
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" xmlns:vm="using:ListView.ViewModel" />
</Application.Resources>

Now create a View.xaml file and add datacontext
DataContext="{Binding Source={StaticResource Locator},Path=ListViewGroupViewModel}"

Add CollectionViewSource to Page resources and set the source as GroupTasks property from the view model.
<Page.Resources>
<CollectionViewSource x:Name="csvTasks" IsSourceGrouped="True" Source="{Binding GroupTasks}"></CollectionViewSource>
</Page.Resources>

Now, start with the SemanticZoom control for which you need to define content for both zoomed in view and zoomed out view as shown below:
<SemanticZoom x:Name="MySemanticZoom">
<SemanticZoom.ZoomedInView>
// Zoomed in ui
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
// Zoomed out ui
</SemanticZoom.ZoomedOutView>
</SemanticZoom>

Adding a ListView into the xaml to define the content for the zoomed in view:
<SemanticZoom.ZoomedInView>
<ListView ItemsSource="{Binding Source={StaticResource csvTasks}}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Grid Height="70"
Margin="0,0,10,0" Width="370" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"></ColumnDefinition>
<ColumnDefinition Width="0.8*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Stretch="Fill" Source="../Assets/people_default.png" MaxHeight="50"
MaxWidth="40"
MinWidth="50"
MinHeight="50"></Image>
<TextBlock Grid.Column="1" Text="{Binding TaskName}" VerticalAlignment="Center" Foreground="Black" FontSize="20"></TextBlock>
</Grid>
</StackPanel>
<Line X1="0"
Y1="2"
X2="600"
Y2="2"
Stroke="Gray"
StrokeThickness="1"
Margin="0,0,0,5"
Grid.ColumnSpan="3"
VerticalAlignment="Bottom" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="True">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Border MinWidth="400" Background="#FFFFCC" BorderThickness="1" BorderBrush="Gray"
Margin="0,10,5,0" CornerRadius="1">
<TextBlock Foreground="Black"
Text="{Binding Key,Converter={StaticResource TypeToTextConverter}}"
Margin="10,2,2,5" TextTrimming="WordEllipsis" TextWrapping="NoWrap"
FontWeight="SemiBold" FontSize="10"></TextBlock>
</Border>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</SemanticZoom.ZoomedInView>

Notice that this binds to the CollectionViewSource we defined earlier and since the CollectionViewSource is defined as being grouped we need to supply a DataTemplate to define how the group headers are displayed.

And for the zoomed out view:
<SemanticZoom.ZoomedOutView>
<ListView Margin="5" ItemsSource="{Binding Source={StaticResource csvTasks},Path=CollectionGroups}"
Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="99" Margin="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Border Background="Red"
Width="200" Height="111">
<Grid>
<TextBlock Text="{Binding Group.Key,Converter={StaticResource TypeToTextConverter}}"
Style="{ThemeResource SubheaderTextBlockStyle}" />
</Grid>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>

</ListView>
</SemanticZoom.ZoomedOutView>

Note that the ListView binds its ItemsSource to the CollectionGroups property of the CollectionViewSource.

In Windows Phone 8.1, they are missing the standard semantic zoom template for switching Zommed In and Zoomed out view with + or -. Rather click the group header in Zoomed In view to get the Zoomed out view items, then clicks on the Zoomed out view item to display the zoomed in view.

Download the working sample from below location.
http:// nullskull.com/FileUpload/-407123783_ListView.zip

By Siva Jagan Dhulipalla   Popularity  (3584 Views)