Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply style to first child?

Tags:

c#

wpf

xaml

Is there some way to apply styles to the first (or last or nth) child of a container (anything that contains children)? I am trying to customize the look of tab items so that the first one has different border radius than the others.

This is what I have now:

<ControlTemplate TargetType="{x:Type TabItem}">
    <Grid>
        <Border Name="Border" BorderBrush="#666" BorderThickness="1,1,1,0" CornerRadius="8,8,0,0" Margin="0,0,0,-1">
            <TextBlock x:Name="TabItemText" Foreground="#444" Padding="6 2" TextOptions.TextFormattingMode="Display">
                <ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Header" Margin="12,2,12,2"/>
            </TextBlock>
        </Border>
    </Grid>
</ControlTemplate>
like image 665
Tower Avatar asked Feb 25 '12 13:02

Tower


People also ask

How do I select the first child of a parent CSS?

The :first-child selector is used to select the specified selector, only if it is the first child of its parent.

How do I target a direct child in CSS?

The child combinator ( > ) is placed between two CSS selectors. It matches only those elements matched by the second selector that are the direct children of elements matched by the first. Elements matched by the second selector must be the immediate children of the elements matched by the first selector.

How do I select the first and last child in CSS?

How to select an element that is the first or last child of its parent. The :first-child pseudo class means "if this element is the first child of its parent". :last-child means "if this element is the last child of its parent". Note that only element nodes (HTML tags) count, these pseudo-classes ignore text nodes.


1 Answers

For ItemsControl derived classes (such as TabControl), you can use the ItemContainerStyleSelector dependency property. When this dependency property is set, ItemsControl will call StyleSelector.SelectStyle() for each item in the control. This will allow you to use different styles for different items.

The following example changes the last tab item in a TabControl so its text is bold and a bit larger than the other tabs.

First, the new StyleSelector class:

class LastItemStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
        var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
        var index = itemsControl.ItemContainerGenerator.IndexFromContainer(container);

        if (index == itemsControl.Items.Count - 1)
        {
            return (Style)itemsControl.FindResource("LastItemStyle");
        }

        return base.SelectStyle(item, container);
    }
}

This style selector will return the style with the key "LastItemStyle" but only for the last item in the control. The other items will use the default style. (Note, that this function only uses members from ItemsControl. It could also be used for other ItemsControl derived classes.) Next, in your XAML, you first need to create two resources. The first resource will be to this LastItemStyleSelector and the second resource is the style.

<Window.Resources>
    <local:LastItemStyleSelector x:Key="LastItemStyleSelector" />

    <Style x:Key="LastItemStyle" TargetType="TabItem">
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="FontSize" Value="16" />
    </Style>
</Window.Resources>

Then finally your TabControl:

    <TabControl ItemContainerStyleSelector="{StaticResource LastItemStyleSelector}">
        <TabItem Header="First" />
        <TabItem Header="Second" />
        <TabItem Header="Third" />
    </TabControl>

For more information see the MSDN documentation:

  • ItemsControl.ItemContainerStyleSelector Property
  • StyleSelector Class
like image 187
Lee Berger Avatar answered Sep 22 '22 22:09

Lee Berger