I'm using Flipview and a DataTemplateSelector to determine at runtime which DataTemplate to apply to show items in my control.
I have two DataTemplate's, one is static and the second can be used by a undetermined number of items.
Currently
My first view displays: - "This is a test - Content"
Followed by 18 other views
that look like this:
- "http://www.google.com/ 0"
- "http://www.google.com/ 1"
- "http://www.google.com/ 2"
- and so on until 17
I want
The items "http://www.google.com/ " to be grouped as 3 on a view
.
For example the second view will display:
The third view will display:
And so on..
Bellow is my code:
FlipViewDemo.xaml
<Page.Resources>
<DataTemplate x:Key="FirstDataTemplate">
<Grid>
<TextBlock Text="{Binding Content}" Margin="10,0,18,18"></TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="SecondDataTemplate">
<TextBox Text="{Binding Url}"></TextBox>
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
FirstTextTemplate="{StaticResource FirstDataTemplate}"
SecondTextTemplate="{StaticResource SecondDataTemplate}">
</local:MyDataTemplateSelector>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<FlipView x:Name="itemGridView" ItemTemplateSelector="{StaticResource MyDataTemplateSelector}"
Margin="265,220,284,162">
</FlipView>
</Grid>
FlipViewDemo.xaml.cs
public sealed partial class FlipViewDemo : Page
{
public FlipViewDemo()
{
this.InitializeComponent();
var items = new List<BaseClass>();
items.Add(new FirstItem
{
Content="This is a test - Content"
});
for (int i = 0; i < 18; i++)
{
items.Add(new SecondItem
{
Url = "http://www.google.com/ " + i.ToString()
});
}
itemGridView.ItemsSource = items;
}
}
public class BaseClass
{
}
public class FirstItem : BaseClass
{
public string Content { get; set; }
}
public class SecondItem : BaseClass
{
public string Url { get; set; }
}
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate FirstTextTemplate { get; set; }
public DataTemplate SecondTextTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item,
DependencyObject container)
{
if (item is FirstItem)
return FirstTextTemplate;
if (item is SecondItem)
return SecondTextTemplate;
return base.SelectTemplateCore(item, container);
}
}
I'm thinking that maybe this can be achieved with groups and list view. But I'm not sure how this can be done.
Probably it is a stupid question but, using Google, I can't find an answer. Also english is not my native language; please excuse typing errors.
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}" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With