How to change appearance of TabItems in a scrolling WPF TabControl? - c#

I have a scrolling TabControl, using a ScrollViewer and StackPanel (with the StackPanel set as IsItemsHost="true"). To begin with, I am working from a solution originally outlined here - Creating Scrolling Tabs Using WPF's TabControl . At the moment it has broken links (Edit: I have tracked down one instance of his code in a forum here - How to prevent TabControl from doing multi rows?), so here is the xaml for the TabControl (does not require any further code):
<TabControl x:Name="TabControl2" Height="Auto" TabStripPlacement="Bottom" VerticalAlignment="Bottom" Template="{DynamicResource TabControlControlTemplate1}" IsSynchronizedWithCurrentItem="True">
<TabControl.Resources>
<Style x:Key="TabScrollerRepeatButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Margin="1,0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding ContentControl.Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="TabControlControlTemplate1" TargetType="{x:Type TabControl}">
<Grid x:Name="Grid" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="1" Grid.Column="0" x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,1,1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Border Background="{TemplateBinding Background}" x:Name="Border1">
<ContentPresenter DataContext="{x:Null}" Margin="{TemplateBinding Padding}" x:Name="PART_SelectedContentHost" Content="{TemplateBinding SelectedContent}" ContentTemplate="{TemplateBinding SelectedContentTemplate}" ContentTemplateSelector="{TemplateBinding SelectedContentTemplateSelector}" ContentSource="SelectedContent"/>
</Border>
</Border>
</Border>
<ScrollViewer x:Name="HeaderPanel" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<ScrollViewer.Style>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Margin="0,0,0,0" Grid.Row="0" Grid.Column="0" x:Name="HeaderPanel">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<RepeatButton Grid.Column="1" Content="<" Command="ScrollBar.LineLeftCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}" Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
<ScrollContentPresenter Grid.Column="2" Content="{TemplateBinding ScrollViewer.Content}" />
<RepeatButton Grid.Column="3" Content=">" Command="ScrollBar.LineRightCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}" Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollViewer.Style>
<StackPanel IsItemsHost="true" Orientation="Horizontal" Background="{x:Null}" KeyboardNavigation.TabIndex="1"/>
</ScrollViewer>
</Grid>
</ControlTemplate>
</TabControl.Resources>
<TabItem x:Name="TabItem1" Header="TabItem1"/>
<TabItem x:Name="TabItem2" Header="TabItem2"/>
</TabControl>
How might I adjust the appearance of each TabItem? For instance, I would like to place a TextBox and TextBlock inside each TabItem, with the help of a StackPanel, so that I can have renameable tabs (collapsing one or the other as appropriate). I might also want to add a close button on each tab. Ordinarily, I would use something like the following:
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Name="panel" Orientation="Horizontal">
<TextBox Name="editHeader" Text="{Binding Header}" MaxWidth="250"/>
<TextBlock Name="textHeader" Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
.. but this is having no effect at all. Any ideas would be appreciated. Thanks.
Edit: I am still trying to figure this out. Is it possible that the solution could involve ContentPresenter and/or SelectedContentTemplate?
Edit 2: (this doesn't add value to my question) I really, really wish WPF included something of this sort out of the box. I am baffled by TabControl's default behavior, and by the fact that there is no scrollable TabControl (nor simple solution for attaining one) after some years.

Hey guesser. I've done something similar, I based mine off of this series though
http://www.blogs.intuidev.com/post/2010/post/2010/01/25/TabControlStyling_PartOne.aspx
The method used is to simply style the tabitems template. eg:
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<!-- your custom template goes here -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
Unforunately this method means you will have to completely redefine the way the tab items look and behave. But the provided link gives good examples on how achieve this.
Hope it helps.

Just a thought,
have you tried just adding the text block to the TabItem.Header? If you do this instead of a template it might work. Has for me in the past

I think I've got it (though still crossing fingers a bit -- I haven't yet dealt with Visibility of the TextBlock vs TextBox for renaming).
It is similar to Val's solution in that I'm working in TabControl.Resources on its TabItem, but the Property concerned is HeaderTemplate and I just override the ContentPresenter in a DataTemplate. (measures to avoid replacing\destroying a lot of good behavior that comes for free with the TabControl)
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<ContentPresenter>
<ContentPresenter.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding Content}"/>
<TextBox Text="{TemplateBinding Content}"/>
</StackPanel>
</ContentPresenter.Content>
</ContentPresenter>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
I'm somewhat of a WPF newb, so this is basically a result of persistent experimentation with what I could find Googling. For those interested, this link (on StackOverflow) helped me most in the end - WPF TabItem Header Styling

Related

How do I change the corners of a groupBox to sharp instead of round C# .NET WPF

I just started working with GroupBoxes and I was just wondering why I cant make my corners sharp, as if it was a rectangle.
I've seen a few online and thier corners arent round. Why is that?
<GroupBox x:Name="howTOGroupBox" BorderBrush="White" Foreground="White" Header="How To" HorizontalAlignment="Left" Margin="88,86,0,0" VerticalAlignment="Top" Height="79" Width="221" BorderThickness="1"/>
you can style Your GroupBox ControlTemplate and round to 0 all of the corners:
<Window.Resources>
<Style TargetType="GroupBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="0"
BorderThickness="1" BorderBrush="White"
CornerRadius="0,0,0,0">
<ContentPresenter
ContentSource="Header"
RecognizesAccessKey="True" />
</Border>
<Border Grid.Row="1" BorderBrush="White"
BorderThickness="1"
CornerRadius="0,0,0,0">
<ContentPresenter Margin="4" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
I used the recommendation Answer before and modified it a little bit:
<Window.Resources>
<Style TargetType="GroupBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5px" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Header -->
<Border Grid.Row="1" Grid.Column="0" BorderThickness="1,1,0,0" BorderBrush="Black" CornerRadius="0,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
<Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="1">
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True" />
</Label>
<Border Grid.Row="1" Grid.Column="2" BorderThickness="0,1,1,0" BorderBrush="Black" CornerRadius="0,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>
<!-- Content -->
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="1,0,1,1" CornerRadius="0,0,0,0" Padding="10,10,10,10" Margin="0,0,0,0">
<ContentPresenter Margin="4" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
I know I'm very late to the party on this one but... here's a fairly robust, if not rather more complicated than it should be, like a lot of things in WPF, answer.
Firstly, I'm not sure why there isn't a just a CornerRadius property on the GroupBox control itself. It feels like that could have been implemented quite easily.
Secondly, the reason you can't just create a Style that targets the CornerRadius of Border controls in the GroupBox is, when you look at how the framework composes a GroupBox from other controls, the CornerRadius properties of the Border controls it uses are hard set to the value 2. i.e. they can't be overridden by a Style element.
To See how the WPF team originally created the GroupBox control, and to use this as a base for a square-corned GroupBox, right-click on one in the designer and select Edit Template then Edit a Copy.... This will then create a Style which targets GroupBox and overrides its default Template with a copy of exactly how the GroupBox control is normally composed. It will create something like the below. The simplest thing to do next is to go through and change all the CornerRadius elements to 0 and then reference the style as such: <GroupBox Header="Blah" Style="{StaticResource SquareCornerGroupBox}" />
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style x:Key="SquareCornerGroupBox" TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush" Value="#D5DFE5"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="6"/>
</Grid.RowDefinitions>
<Border Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4" Grid.Column="0" Grid.ColumnSpan="4" Grid.RowSpan="3" Grid.Row="1"/>
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4" Grid.ColumnSpan="4" Grid.RowSpan="3" Grid.Row="1">
<Border.OpacityMask>
<MultiBinding ConverterParameter="7" Converter="{StaticResource BorderGapMaskConverter}">
<Binding ElementName="Header" Path="ActualWidth"/>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Border.OpacityMask>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Border>
</Border>
<Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.RowSpan="2" Grid.Row="0">
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ContentPresenter Grid.Column="1" Grid.ColumnSpan="2" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF ProgressBar Width not sizing to Text

I am having an issue with the Microsoft WPF ProgressBar. I will set Width="Auto" and the width will size to the text width until a value property of ~97. Between values 97 and 100 the control will go exponentially larger until it hits MaxWidth.
The following style is setting the template for the ProgressBar. I can't seem to find anything that will cause it to behave until a Value of ~97. I do not touch the width in the code behind.
<Style x:Key="CurrentDayProgressBar" TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid>
<Border Name="PART_Track" CornerRadius="2" Background="DarkGray" BorderBrush="{DynamicResource TextBrush}" BorderThickness="1" />
<Border Name="PART_Indicator" CornerRadius="2" Background="{DynamicResource ProgressBarBackground}" HorizontalAlignment="Left" Margin="2" />
<TextBlock Name="PART_Text" Margin="2" Width="Auto" Padding="5,0,5,0" Text="{Binding RelativeSource={RelativeSource AncestorType=ProgressBar}, Path=Tag}"
Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{DynamicResource SimpleTextBlock}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The first image below is what the bar looks like when it is at a Value of 99.2. The second is my implementation in the Telerik RadProgressBar, which behaves like I expect it to. The Telerik solution may be what I have to go with, but it would be nice to know why the Microsoft control is not working.
WPF ProgressBar Control
Telerik RadProgressBar and Textbox
The PART_Track cannot have any extra margins/borders attached to it and/or the PART_Indicator should be nested inside it. To resolve the problem you're having, do something like:
<Border CornerRadius="2" Background="DarkGray" BorderBrush="{DynamicResource TextBrush}" BorderThickness="1" />
<Border x:Name="PART_Track" Margin="3">
<Border Name="PART_Indicator" CornerRadius="2" Background="{DynamicResource ProgressBarBackground}" HorizontalAlignment="Left" />
</Border>
<TextBlock ... />

Right align panorama header

It seems that there should be a very easy solution to this but I cannot find it and it's killing me ...
All I wanna do is to add a right aligned refresh button (or image, or whatever) to the Header of a PanaromaItem in a Panorama, so pressing it reloads the data. (look at the image below)
I tried overriding the PanoramaItem.Header:
<phone:PanoramaItem.Header>
<Grid>
<TextBlock Text="first item" />
<Image source="blah" HorizontalAlignment="Right" />
</Grid>
</phone:PanoramaItem.Header>
and I tried using Grid, StackPanel, ViewPanel and every other layout controller that I knew and couldn't achieve this unless I set a constant width.
Any idea?
Might as well answer this one correctly, just incase someone needs it.
You need to override the PanoramaItemStyle and set the Header ContentControl to Stretch.
HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"
That way when you apply the template it will cover the whole width. Here is the full Override Style Template.
<phone:PhoneApplicationPage.Resources>
<Style x:Key="Chubs_PanoramaItemStyle" TargetType="phone:PanoramaItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:PanoramaItem">
<Grid Background="{TemplateBinding Background}" Margin="12,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl x:Name="header" CharacterSpacing="-35" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" FontSize="66" FontFamily="{StaticResource PhoneFontFamilySemiLight}" Margin="12,-2,0,38" HorizontalContentAlignment="Stretch">
<ContentControl.RenderTransform>
<TranslateTransform x:Name="headerTransform"/>
</ContentControl.RenderTransform>
</ContentControl>
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Grid.Row="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
Now apply that style to the PanoramaItem like so
<phone:PanoramaItem Style="{StaticResource Chubs_PanoramaItemStyle}">
<phone:PanoramaItem.Header>
<Grid>
<TextBlock Text="header1"/>
<Image Source="/Assets/ApplicationIcon.png" Stretch="None" HorizontalAlignment="Right"></Image>
</Grid>
</phone:PanoramaItem.Header>
</phone:PanoramaItem>
And Screenshot of the results:
By default when we set horizontal alignment to the image within panorama item header then it is not working But we can fix the width of the header textblock and set the alignment right for the image.
<controls:PanoramaItem.Header>
<Grid>
<TextBlock Text="First" Width="400"/>
<Image Source="/ApplicationIcon.png" Width="60" Height="60" HorizontalAlignment="Right" />
</Grid>
</controls:PanoramaItem.Header>
I tried horizontalalign="Right" is not working but to achive this you could set left margin:
<phone:PanoramaItem Header="My Books" Foreground="LightGray" Margin="-10,0,0,0">
<phone:PanoramaItem.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="#72C158" Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Margin="0,30,0,0" FontSize="55" FontFamily="/Font/BKANT.TTF#Book Antiqua" TextAlignment="Left" FontWeight="Normal"/>
<Button Height="50" Width="50" Margin="130,20,0,0"/>
</StackPanel>
</DataTemplate>
</phone:PanoramaItem.HeaderTemplate>
</phone:PanoramaItem>
As described here, you will need to override the pivotitem template to set the HorizontalAlignment of the Header to Stretch.
After that you should be able to align stuff to the right of the header.

WPF ListBox can not set BackgroundColor

I have a problem, that I can not set the background color of my ListBox-Control. I create a ItemsControl template and DataTemplates:
<Style TargetType="ItemsControl" x:Key="LogViewerStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<ScrollViewer CanContentScroll="True">
<ItemsPresenter SnapsToDevicePixels="True" />
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<DataTemplate DataType="{x:Type local:LogEntry}">
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Index}" Grid.Column="0" FontWeight="Normal" Margin="2,0,2,0" Foreground="{Binding Path=LineNumbersColor, ElementName=LogViewerProperty}" Cursor="RightArrow.cur" TextAlignment="Right" />
<TextBlock Text="{Binding DateTime}" Grid.Column="1" FontWeight="Bold" Margin="0,0,5,0" />
<TextBlock Text="{Binding Message}" Grid.Column="2" TextWrapping="{Binding Path=WordWrapping, ElementName=LogViewerProperty, Converter={StaticResource BoolToTextWrap}}" />
</Grid>
</DataTemplate>
When I try to give my ListBox a BackgroundColor nothing happens:
<ListBox ItemsSource="{Binding}" x:Name="LogViewer" Background="Cornsilk" Style="{StaticResource LogViewerStyle}">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" Padding="{TemplateBinding Padding}" HorizontalScrollBarVisibility="{Binding Path=WordWrapping, ElementName=LogViewerProperty, Converter={StaticResource BoolToScrollbarVisibility}}" VerticalScrollBarVisibility="{Binding Path=VerticalScrollbarVisible, ElementName=LogViewerProperty}">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>
At the moment I don't have clue why. Can anybody give me a hint? Thanks!
You apply a style to ListBox with the key LogViewerStyle which futhermore defines a template but then you create another template for ListBox implicitly.
Why? That is not wpf's usual bread. Its not making sence, is it?
Remove one of them please.
Though to answer your question you will have to tell your ScrollViewer to listen to the Background of the ListBox.
Take a look at this:
<Style TargetType="ListBox" x:Key="MyListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter SnapsToDevicePixels="True" />
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
And then just set the style on the ListBox.
<ListBox Style="{StaticResource MyListBox}" />
Take a look how it tells Grid to have its Background same as ListBox will have.
Setting Background="{TemplateBinding Background}" applies background for me
<ListBox ItemsSource="{Binding}" Width="100" x:Name="LogViewer" Background="Red" Style="{StaticResource LogViewerStyle}">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalScrollBarVisibility="{Binding Path=WordWrapping, ElementName=LogViewerProperty, Converter={StaticResource BoolToScrollbarVisibility}}" VerticalScrollBarVisibility="{Binding Path=VerticalScrollbarVisible, ElementName=LogViewerProperty}">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True">
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>

How to Change Pivot Header Template in Windows Phone 8

I would like to be able to change the background of the Pivot Headers and Application Title in Windows Phone 8. From what I gather, I must create a custom style targeting the Pivot control. I am not sure, however, to change the background of only the headers?
I would like to adjust the style somehow
<Style x:Key="MyPivotStyle" TargetType="phone:Pivot">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid CacheMode="BitmapCache" Grid.RowSpan="2">
<Grid.Background>
<ImageBrush ImageSource="/Assets/bg_header.png"/>
</Grid.Background>
</Grid>
<Grid Background="{TemplateBinding Background}" CacheMode="BitmapCache" Grid.Row="2" />
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}" Margin="24,17,0,-7">
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/company_name.png" Width="213.75" HorizontalAlignment="Left" VerticalAlignment="Top" />
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Margin="140,-20,0,35" BorderThickness="0" x:Name="btnHome">
<Image Source="/Assets/btnHome.png" Width="48" Height="48" ></Image>
</Button>
</StackPanel>
</ContentPresenter>
<controlsPrimitives:PivotHeadersControl x:Name="HeadersListElement" Foreground="White" Grid.Row="1"/>
<ItemsPresenter x:Name="PivotItemPresenter" Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
EDITED for WinRT (sorry for the delay and thanks for the reminder to update this answer):
To edit a full template right click on the control when in Document Outline and select Edit Template - Current (in Visual Studio or Blend) and the template will be generated for you and you can edit as you want, see my answer here for screenshots.
Here are the two examples below (posted in 2013) redone for Windows Phone Windows Runtime:
<Grid Background="Transparent">
<Pivot Title="Re-templating example">
<Pivot.HeaderTemplate>
<DataTemplate>
<Grid Background="Blue">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.TitleTemplate>
<DataTemplate>
<Grid Background="Green">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</Pivot.TitleTemplate>
<PivotItem Header="One">
<TextBlock FontSize="35"
Text="This is item one" />
</PivotItem>
<PivotItem Header="Two">
<TextBlock FontSize="35"
Text="This is item 2" />
</PivotItem>
</Pivot>
</Grid>
And second example, notice that we are wrapping the ContentPresenter in a Grid (you could use a border as well or any other element):
<Page.Resources>
<SolidColorBrush x:Key="PivotBackground" Color="#FFE46C08"/>
<Style x:Key="PivotStyle" TargetType="Pivot">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Pivot">
<Grid x:Name="RootElement" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Notice that ContentControl is wrapped in a Grid and Background set to resource furtehr up-->
<Grid VerticalAlignment="Center" Background="{StaticResource PivotBackground}">
<ContentControl x:Name="TitleContentControl" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" Style="{StaticResource PivotTitleContentControlStyle}"/>
</Grid>
<ScrollViewer x:Name="ScrollViewer" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="Hidden" Margin="{TemplateBinding Padding}" Grid.Row="1" Template="{StaticResource ScrollViewerScrollBarlessTemplate}" VerticalSnapPointsType="None" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalContentAlignment="Stretch" ZoomMode="Disabled">
<PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
<!--Background set to resource further up-->
<PivotHeaderPanel Background="{StaticResource PivotBackground}" x:Name="Header" >
<PivotHeaderPanel.RenderTransform>
<CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0"/>
</PivotHeaderPanel.RenderTransform>
</PivotHeaderPanel>
<ItemsPresenter x:Name="PivotItemPresenter">
<ItemsPresenter.RenderTransform>
<TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0"/>
</ItemsPresenter.RenderTransform>
</ItemsPresenter>
</PivotPanel>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
Using the above style:
<Grid Background="Transparent">
<Pivot Style="{StaticResource PivotStyle}"
Title="Re-templating example">
<PivotItem Header="One">
<TextBlock FontSize="35" Text="This is item one" />
</PivotItem>
<PivotItem Header="Two">
<TextBlock FontSize="35" Text="This is item 2"/>
</PivotItem>
</Pivot>
</Grid>
By the way, it's usually preferred to keep styles in a separate style file- I've only kept them on the same page for simplicity for this example. If you remove the x:key attribute the style will be applied to all the controls of the set target type (Pivot in this example).
Answer from 2013 for Windows Phone 7.X and Windows Phone 8 (WP Silverlight:
There are a few ways you can do it, but here is one example:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<phone:Pivot Grid.Row="1">
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<Grid Background="Red" Height="200">
<TextBlock Text="{Binding}"/>
</Grid>
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:PivotItem Header="Test">
<TextBlock Text="ghjgb"/>
</phone:PivotItem>
<phone:PivotItem Header="Test">
<TextBlock Text="ghjgb"/>
</phone:PivotItem>
</phone:Pivot>
If you however want to do this:
You can do this, remove the x:key to apply to all pivoits, or use the key to set the style on just selected pivoit elements like so:
<controls:Pivot Title="The Marathon Runner" Style="{StaticResource PivotStyle}">
<Style x:Key="PivotStyle" TargetType="phone:Pivot">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Background="#ff9000" CacheMode="BitmapCache" Grid.RowSpan="2" />
<Grid Background="{TemplateBinding Background}" CacheMode="BitmapCache"
Grid.Row="2" />
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}"
Content="{TemplateBinding Title}" Margin="24,17,0,-7"/>
<Primitives:PivotHeadersControl x:Name="HeadersListElement"
Grid.Row="1"/>
<ItemsPresenter x:Name="PivotItemPresenter"
Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Dont forget to use:
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:Primitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone"

Categories