Dynamically displaying Items using FlipView and DataTemplateSelector in WinRT Dynamically displaying Items using FlipView and DataTemplateSelector in WinRT wpf wpf

Dynamically displaying Items using FlipView and DataTemplateSelector in WinRT


I think the way to achieve what you are looking for is to expose the data in a way that better represents what you want to display. Then, you can use nested controls to display it. I just threw this together (using my own test data). It is probably not exactly what you want, but it should help you figure things out.

ViewModel
Here I made a helper method to build the collection with sub-collections that each have 3 items.

class FlipViewDemo{    private List<object> mData;    public IEnumerable<object> Data    {        get { return mData; }    }    public FlipViewDemo()    {        mData = new List<object>();        mData.Add("Test String");        for (int i = 0; i < 18; ++i)        {            AddData("Test Data " + i.ToString());        }    }    private void AddData(object data)    {        List<object> current = mData.LastOrDefault() as List<object>;        if (current == null || current.Count == 3)        {            current = new List<object>();            mData.Add(current);        }        current.Add(data);    }}class TemplateSelector : DataTemplateSelector{    public DataTemplate ListTemplate { get; set; }    public DataTemplate ObjectTemplate { get; set; }    public override DataTemplate SelectTemplate(object item, DependencyObject container)    {        if (item is List<object>) return ListTemplate;        return ObjectTemplate;    }}

Xaml
Here I use an ItemsControl to vertically stack the items in the data. Each item is either a list of three objects or a single object. I use a FlipView for each of the lists of three objects and a simple ContentPresenter for the single objects.

<Page.Resources>    <DataTemplate x:Key="ListTemplate">        <FlipView            ItemsSource="{Binding}">            <FlipView.ItemTemplate>                <DataTemplate>                    <ContentPresenter                        Margin="0 0 10 0"                        Content="{Binding}" />                </DataTemplate>            </FlipView.ItemTemplate>        </FlipView>    </DataTemplate>    <DataTemplate x:Key="ObjectTemplate">        <ContentPresenter            Margin="0 0 10 0"            Content="{Binding}" />    </DataTemplate>    <local:TemplateSelector        x:Key="TemplateSelector"        ListTemplate="{StaticResource ListTemplate}"        ObjectTemplate="{StaticResource ObjectTemplate}" /></Page.Resources><ItemsControl    ItemsSource="{Binding Data}"    ItemTemplateSelector="{StaticResource TemplateSelector}" />

Note: You usually would not need a template selector for something like this, but since you need to select between a List<T> and an Object, there is no way I know of to recognize the difference using only the DataTemplate.TargetType property from Xaml due to List<t> being a generic type. (I tried {x:Type collections:List`1} and it did not work.)


You need to group items in viewmodel, and databind ItemsSource to the groups. In flipview's itemtemplate you display items in group.

public class PageGroup : PageBase {    public ObservableColection<BaseClass> Items { get; set; }}public ObservableCollection<PageBase> Pages { get; set; }
<FlipView ItemsSource="{Binding Pages}">     <FlipView.ItemTemplate>         <DataTemplate DataType="local:PageGroup">             <ItemsControl ItemsSource="{Binding Items}"                           ItemTemplateSelector="{StaticResource MyDataTemplateSelector}" />         </DataTemplate>     </FlipView.ItemTemplate> </FlipView>

In order to display first page differently from others:

public class FirstPage : PageBase {    public string Title { get; }}Pages.Insert(0, new FirstPage());

and you need to use another datatemplaeselector or impicit datatemplates in FlipView to differentiate between FirstPage and PageGroup

<FlipView ItemsSource="{Binding Pages}"           ItemTemplateSelector="{StaticResource PageTemplateSelector}" />


You don't need to worry about selecting the appropriate template based on the class type, you can simply define the class in the DataTemplate itself.

<DataTemplate TargetType="{x:Type myNamespace:FirstItem}">   ...</DataTemplate>

You'll need to specify where the class is by adding the namespace at the top of your page:

xmlns:myNamespace="clr-namespace:MyApp.MyNamespace"