This is for a Universal Windows App.
Please can you tell me how to modify only the first element of a ListView? I tried to use a header template, but I couldn't work out how to bind it to the first element in my Steps list.
The only difference between the first element and the other elements is that the shape of the first edge will be straight. The first element will not have this styling: Data="M0,0 10,0 10,30 0,30 10,15"
UPDATE: I've got it working using a template selector (DataTemplateSelector). This means I have to give every item a position number. Any better solutions much appreciated!
Here is my XAML:
<Page
x:Class="CloserCrumbs.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CloserCrumbs"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.DataContext>
<local:SuperVM />
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding Steps}" SelectedItem="{Binding Steps.SelectedItem, Mode=TwoWay}" Height="40" FocusVisualPrimaryThickness="0" FocusVisualSecondaryThickness="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#d0d0d0" />
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding ShortDescription}" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
Your best option here to use here is DataTemplateSelector
. You can get the Index of the item that you are applying template to and apply specific DataTemplate
to it.
So in this case you need 2 DataTemplates
. First without the Arrow ( For the first item) and Second for all other items. You can add them in Page.Resources
on the Page
. So in this case its something like below.
<Page.Resources>
<DataTemplate x:Name="OtherItem">
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Path Data="M0,0 10,0 10,30 0,30 10,15" Fill="#d0d0d0" />
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="FirstItem">
<StackPanel x:Name="t1" Orientation="Horizontal" Margin="-12" Height="30">
<Grid Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,-7,0" Height="30" >
<Grid>
<Rectangle Fill="#d0d0d0" />
<TextBlock Text="{Binding }" Margin="10,5" VerticalAlignment="Center" Foreground="White" MinWidth="60"/>
</Grid>
<Path Data="M0,0 10,15 0,30" Fill="#d0d0d0" />
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</Page.Resources>
If you notice the FirstItem
DataTemplate
does not contain First Path to make it look like a starting arrow.
Below is the code for DataTemplateSelector
public class ItemsDataTemplateSelector : DataTemplateSelector
{
public DataTemplate FirstItem { get; set; }
public DataTemplate OtherItem { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
return (itemsControl.IndexFromContainer(container) == 0) ? FirstItem : OtherItem;
}
}
In the above code, all i am saying is if the index is 0
then apply FirstItem
DataTemplate
else OtherItem
.
Now change your ListView Like below.
<ListView x:Name="listView" VerticalAlignment="Top">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplateSelector>
<local:ItemsDataTemplateSelector FirstItem="{StaticResource FirstItem}"
OtherItem="{StaticResource OtherItem}" />
</ListView.ItemTemplateSelector>
</ListView>
Here I am assigning the DataTemplates in Selector to assign FirstItem
to First Item in the List and others will get OtherItem
Template.
Below is the output from temp data.
Hope this helps
Good Luck.
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