Reputation: 535
I have ItemsControl with bindable itemsource and custom datetemplate for each item. Items are separated by line. But last item has separator too, and that's my problem, how to not render line for last item. I've found this solution, but it's working in WPF:
How can a separator be added between items in an ItemsControl
EDIT: Here is my template:
<ItemsControl Grid.Row="1" ItemsSource="{x:Bind ViewModel.AvailableStatuses}" x:Name="Statuses">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Padding="60,0,60,12"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding ElementName=ContentGrid, Path=DataContext.ChangeStatusCommand}" CommandParameter="{Binding}"/>
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Rectangle StrokeThickness="0.4" Height="0.4" x:Name="Separator"
VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Stroke="#D1D3D4" />
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Stretch">
<Image Source="{Binding Converter={StaticResource SelectContactStatusConverter}}" Margin="0,8,12,8"/>
<TextBlock Text="{Binding Converter={StaticResource EnumContactStatusToTextConverter}}" FontSize="20" VerticalAlignment="Center" Foreground="Black"/>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Upvotes: 3
Views: 5201
Reputation: 125
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
Upvotes: -3
Reputation: 535
I solved my problem this way:
private void Statuses_OnLoaded(object sender, RoutedEventArgs e)
{
var s = (ItemsControl) sender;
var container = s.ContainerFromIndex(0);
var element = container.FindChildren<Rectangle>("Separator");
element.Visibility = Visibility.Collapsed;
}
What do you think?
Upvotes: 1
Reputation: 34286
There's probably a few different ways of doing this, here's my take.
Style your ListView's item containers with the border brush and thickness you want to have, and subscribe to the ContainerContentChanging event:
<ListView ContainerContentChanging="ListView_ContainerContentChanging">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="0,1,0,0"/>
</Style>
</ListView.ItemContainerStyle>
<x:String>1</x:String>
<x:String>2</x:String>
<x:String>3</x:String>
<x:String>4</x:String>
</ListView>
In your code behind:
private void ListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.InRecycleQueue)
{
// Item is being recycled, make sure first item has no border
if (args.ItemIndex == 0)
{
var first = (ListViewItem)sender.ContainerFromIndex(0);
if (first != null)
{
first.BorderThickness = new Thickness(0);
}
}
}
else if (args.ItemIndex == 0)
{
// A new first item
((ListViewItem)args.ItemContainer).BorderThickness = new Thickness(0);
var second = (ListViewItem)sender.ContainerFromIndex(1);
if (second != null)
{
second.ClearValue(BorderThicknessProperty);
}
}
else
{
// A new internal item
((ListViewItem)args.ItemContainer).ClearValue(BorderThicknessProperty);
}
}
I decided on this approach for a few reasons:
EDIT
It looks like you meant for an ItemsControl, not a ListView. If that's the case, then you'd have to do something along Depechie's answer because ItemsControl doesn't have the ContainerContentChanging event (subclass ItemsControl and override PrepareContainerForItemOverride instead), but this likely won't work for dynamic lists with items added and removed at runtime. You'd have to experiment with different solutions if this is important to you.
Upvotes: 7
Reputation: 6142
Maybe it's better to put the seperator on top because that will be easier to detect instead of knowing the last element. Putting it on top will result in 1 line to much for the first item, to resolve this add a binding on the visibility property of the seperator, using a converter. You pass along the item index and if the item index is 1 hide the seperator, otherwise show it.
To get the index of an item, look at an example here: http://www.bendewey.com/index.php/523/alternating-row-color-in-windows-store-listview
Upvotes: 1