asusralis
Topic Author
Posts: 51
Joined: 30 Jul 2018, 05:03

Trouble binding to an ItemsControl from a template.

07 Aug 2019, 03:04

Hello! I'm trying to add separators for all my ItemsControls. This is what I have so far:
<Style TargetType="ItemsControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ItemsControl">
                    <StackPanel>
                        <Rectangle
                            x:Name="Separator"
                            Height="1"
                            Margin="10,5"
                            Fill="White" />
                        <ItemsPresenter />
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}, Path=AlternationIndex}" Value="0">
                            <Setter TargetName="Separator" Property="Visibility" Value="Collapsed" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
It seems I can't find the ItemsControl because the separator never shows. What am I doing wrong?
 
User avatar
sfernandez
Site Admin
Posts: 1624
Joined: 22 Dec 2011, 19:20

Re: Trouble binding to an ItemsControl from a template.

07 Aug 2019, 12:54

Where exactly do you want that "Separator" to show? In between each item?
 
asusralis
Topic Author
Posts: 51
Joined: 30 Jul 2018, 05:03

Re: Trouble binding to an ItemsControl from a template.

07 Aug 2019, 16:41

Yes, exactly - I want the rectangle to show between each element in the ItemsSource, but not at the top of the first element or the bottom of the last. I found a similar question for this, but I can't seem to do it through the style. If there's an easier way I'd love to try it, but using the AlternationIndex seemed the less intrusive to me.
 
User avatar
sfernandez
Site Admin
Posts: 1624
Joined: 22 Dec 2011, 19:20

Re: Trouble binding to an ItemsControl from a template.

07 Aug 2019, 17:31

You have to define the ItemTemplate used to render each of the items in the list so you can specify the "Separator" for each item, not in the ItemsControl template which will appear only once:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.Resources>
        <GradientStopCollection x:Key="list">
            <GradientStop Offset="0" Color="Red"/>
            <GradientStop Offset="0.2" Color="Yellow"/>
            <GradientStop Offset="0.4" Color="Green"/>
            <GradientStop Offset="0.6" Color="Cyan"/>
            <GradientStop Offset="0.8" Color="Blue"/>
            <GradientStop Offset="1" Color="Magenta"/>
        </GradientStopCollection>
        <DataTemplate x:Key="itemTemplate">
            <StackPanel>
                <Rectangle x:Name="separator" Height="4" Fill="White"/>
                <Grid>
                    <Rectangle Height="50">
                        <Rectangle.Fill>
                            <SolidColorBrush Color="{Binding Color}"/>
                        </Rectangle.Fill>
                    </Rectangle>
                    <TextBlock Text="{Binding Offset}" Foreground="Gray" TextAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </StackPanel>
            <DataTemplate.Triggers>
                <DataTrigger
                    Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}"
                    Value="0">
                    <Setter TargetName="separator" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </Grid.Resources>
    <Border Background="Gray">
        <ItemsControl x:Name="items"
            ItemsSource="{StaticResource list}"
            ItemTemplate="{StaticResource itemTemplate}"
            AlternationCount="{Binding ItemsSource.Count, RelativeSource={RelativeSource Self}}"
            Width="200" VerticalAlignment="Center"/>
    </Border>
</Grid>
 
asusralis
Topic Author
Posts: 51
Joined: 30 Jul 2018, 05:03

Re: Trouble binding to an ItemsControl from a template.

08 Aug 2019, 21:53

I wanted it where all the DataTemplates have a separator in the ItemsControl. I use a selector for multiple DataTemplates, so if I understand correctly I'd have to put a separator in all of them? Is there any way to automatically have a separator for an ItemsControl without changing the DataTemplate?

Something like this:
<ListBox.ItemContainerStyle>                
    <Style TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <StackPanel>
                        <Separator x:Name="Separator"/>
                        <ContentPresenter/>
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
                            <Setter Property="Visibility" TargetName="Separator" Value="Collapsed"/>
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ListBox.ItemContainerStyle>
 
User avatar
sfernandez
Site Admin
Posts: 1624
Joined: 22 Dec 2011, 19:20

Re: Trouble binding to an ItemsControl from a template.

09 Aug 2019, 11:23

For a basic ItemsControl the container type is a ContentPresenter so there is no other way to customize item representation than DataTemplates.

But if you are using a ListBox then the container is a ListBoxItem, a control that has its own ControlTemplate, so you can create a single Style for all your lists:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid.Resources>
        <GradientStopCollection x:Key="list">
            <GradientStop Offset="0" Color="Red"/>
            <GradientStop Offset="0.2" Color="Yellow"/>
            <GradientStop Offset="0.4" Color="Green"/>
            <GradientStop Offset="0.6" Color="Cyan"/>
            <GradientStop Offset="0.8" Color="Blue"/>
            <GradientStop Offset="1" Color="Magenta"/>
        </GradientStopCollection>
        <ControlTemplate x:Key="listItemTemplate" TargetType="ListBoxItem">
            <DockPanel>
                <Rectangle DockPanel.Dock="Top" x:Name="separator" Height="4" Fill="White"/>
                <ContentPresenter DockPanel.Dock="Bottom"/>
            </DockPanel>
            <ControlTemplate.Triggers>
                <DataTrigger
                    Binding="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}"
                    Value="0">
                    <Setter TargetName="separator" Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <Style x:Key="listItemStyle" TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
            <Setter Property="Template" Value="{StaticResource listItemTemplate}"/>
        </Style>
        <DataTemplate x:Key="itemTemplate">
            <Grid>
                <Rectangle Height="50">
                    <Rectangle.Fill>
                        <SolidColorBrush Color="{Binding Color}"/>
                    </Rectangle.Fill>
                </Rectangle>
                <TextBlock Text="{Binding Offset}" Foreground="Gray" TextAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
        </DataTemplate>
    </Grid.Resources>
    <Border Background="Gray">
        <ListBox
            ItemsSource="{StaticResource list}"
            ItemTemplate="{StaticResource itemTemplate}"
            ItemContainerStyle="{StaticResource listItemStyle}"
            AlternationCount="{Binding ItemsSource.Count, RelativeSource={RelativeSource Self}}"
            Width="200" VerticalAlignment="Center"/>
    </Border>
</Grid>
 
asusralis
Topic Author
Posts: 51
Joined: 30 Jul 2018, 05:03

Re: Trouble binding to an ItemsControl from a template.

09 Aug 2019, 22:44

Oh, I'm sorry to hear that :( Thanks for the information!

Who is online

Users browsing this forum: Google [Bot], sfernandez and 2 guests