Silverlight create control template for TabControl - silverlight

I use Silverlight 5 and want to use control template for TabControl. how can do it.
In WPF you can use below code for control template of TabControl
<Style TargetType="{x:Type TabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<TabPanel Grid.Column="1" Name="HeaderPanel" IsItemsHost="True"/>
<ContentPresenter Grid.Column="0" ContentSource="SelectedContent"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks in advance.

By far the easiest way to customise the TabControl template is with Expression Blend.
However, the ControlTemplate for a Silverlight TabControl should look mostly the same as your example. There are a couple of notable differences though.
TargetType syntax is different
TargetType="TabControl"
There is also no ContentSource property on the ContentPresenter

Related

Why does my ControlTemplate for Grid not work?

I want to set the ControlTemplate of grid to look like this:
Here is the markup:
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.1*"></ColumnDefinition>
<ColumnDefinition Width="0.8*"></ColumnDefinition>
<ColumnDefinition Width="0.1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.1*"></RowDefinition>
<RowDefinition Height="0.8*"></RowDefinition>
<RowDefinition Height="0.1*"></RowDefinition>
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="1" Grid.Column="1"></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Style>
<Border Background="Red"></Border>
</Grid>
I don't know why the ControlTemplate doesn't work. Is there something wrong with my markup?
Grid.RowDefinitions and Grid.ColumnDefinitions are no Dependency properties, and can't be set by a Style. I guess this is why you used a ControlTemplate instead of setting it directly. But the default Style of the ControlTemplate does not show any Borders/Lines, therefore you may want to use a ContentPresenter (Wrap it around your Grid and not inside of it).
Additionally: To place the Border in the Center of the Grid, you must set the Row and Column, otherwise the Border is spread across the whole Grid. And place it right there where you have your ContentPresenter inside the Controltemplate, not outside of it.
Edit
Due to the clarification in the comments i suggest to use a Border which shrinks the Content with a RenderTransform.
Style
<Style x:Name="Shrink80pcBorder" TargetType="{x:Type Border}">
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
</Setter.Value>
</Setter>
</Style>
Usage
<Border Background="Red" Style="{StaticResource Shrink80pcBorder}">
<Your Item/Content/>
</Border>

Button Style in Resource not Applied to Buttons

Can someone please explain to me why this doesn't work? The Buttons in the ToolBar are not getting the Black BorderBrush property setting. I've tried TargetType="Button" and TargetType="{x:Type Button}" but neither work. I've done almost exactly the same thing for a series of Labels and it worked fine. I'm pretty new to WPF. Is there something I'm not understanding about style precedence here? Thanks!
...Window Definition...
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="Black" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToolBar Grid.Column="0" Grid.Row="0" Margin="0">
<Button>
<StackPanel Orientation="Horizontal" Height="Auto">
<Rectangle Width="16" Height="16" Fill="LightBlue" VerticalAlignment="Center"></Rectangle>
<Label Padding="0" VerticalAlignment="Center" HorizontalAlignment="Left">Redraw</Label>
</StackPanel>
</Button>
... More Buttons ...
</ToolBar>
</Grid>
... End Window Definition ...
here you go
<Style x:Key="{x:Static ToolBar.ButtonStyleKey}"
TargetType="{x:Type Button}">
<Setter Property="BorderBrush"
Value="Black" />
</Style>
from How to: Style Controls on a ToolBar
The ToolBar defines ResourceKey objects to specify the style of controls within the ToolBar. To style a control in a ToolBar, set the x:key attribute of the style to a ResourceKey defined in ToolBar.
The ToolBar defines the following ResourceKey objects:
ButtonStyleKey
CheckBoxStyleKey
ComboBoxStyleKey
MenuStyleKey
RadioButtonStyleKey
SeparatorStyleKey
TextBoxStyleKey
ToggleButtonStyleKey

Nested ContentControls with template

I have a custom WindowStyle, the XAML looks like this:
<Style TargetType="{x:Type Window}"
x:Key="WindowStyle">
/** Some setters **/
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<AdornerDecorator>
<Grid Background="#88000000"
x:Name="WindowBackgroundGrid">
<Border x:Name="WindowContentBorder"
Background="{DynamicResource WindowBackground}"MaxHeight="{Binding Source={x:Static SystemParameters.FullPrimaryScreenHeight}}"
MaxWidth="{Binding Source={x:Static SystemParameters.FullPrimaryScreenWidth}}"
Margin="20">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Header -->
<Border BorderBrush="{DynamicResource BorderBrushColor}"
Background="{DynamicResource PaneHeader_Background}"
Grid.Row="0">
<TextBlock Text="Title"Foreground="{DynamicResource DefaultForeground}"
FontSize="16"
FontWeight="Bold"
Margin="5,5,2,5" />
</Border>
<!-- Content -->
<ScrollViewer Grid.Row="1"
Margin="5">
<ContentPresenter Content="{TemplateBinding Content}" />
</ScrollViewer>
</Grid>
</Border>
</Grid>
</AdornerDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I want the inner Grid in a seperate Style so that I can use it elsewhere.
<Style x:Key="WindowContentStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Header -->
/** Border control **/
<!-- Content -->
<ScrollViewer Grid.Row="1"
Margin="5">
<ContentPresenter Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" />
</ScrollViewer>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
And I use a ContenPresenter in my WindowStyle to present it:
<ContentPresenter>
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}"
BasedOn="{StaticResource WindowContentStyle}" />
</ContentPresenter.Style>
</ContentPresenter>
Problem
The edit above didn't give me any errors, but it doesn't present my WindowContentStyle.
When I set the Content property of the Window control and load the style
this.window.Content = view;
this.window.Style = (Style)Application.Current.TryFindResource("WindowStyle");
the content is shown in the ContentPresenter in the WindowStyle and not in WindowContentStyle. Because of this, the Template is not used and I don't have a header with a title.
How can I make my outer ContentPresenter pass on the Content to my inner ContentPresenter (the one in WindowContentStyle)?
Thanks in advance!
Greetings
Loetn
You should use a ContentControl to display your content, not a ContentPresenter. From the ContentPresenter Class page on MSDN:
You typically use the ContentPresenter in the ControlTemplate of a ContentControl to specify where the content is to be added.
From the ContentControl Class page on MSDN:
A ContentControl has a limited default style. If you want to enhance the appearance of the control, you can create a new DataTemplate.

TabItem - how to change template and leave default style?

I have the following code:
<Window x:Class="kkk.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="tabitemstyle" TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="ContentSite" ContentSource="Header"></ContentPresenter>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Header="tab1" Style="{StaticResource tabitemstyle}"></TabItem>
<TabItem Header="tab1" Style="{StaticResource tabitemstyle}"></TabItem>
</TabControl>
</Grid>
</Window>
I want to preserve the default style of TabItem - I mean the padding/margins/BorderBrush/BorderThickness and so on... That is why I wrote BasedOn="...".
But it doesn't work - I thought it will render same as TabItem without any custom style but it doesn't - it just renders some text (by the ContentPresenter). The style doesn't get default properties values... How I can do it?
And I need the ControlTemplate inside my style...
You are overwriting the TabItem.Template, which is what tells WPF how to draw the object
If you want to create a template that is based on the default TabItem.Template, you can get the default template from MSDN and alter it to whatever you want.

Does anyone have a simple example of a UserControl with a single ContentPresenter?

So far, I have this:
<UserControl
x:Class="MyConcept.ExpanderPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Border
Style="{StaticResource Border_PanelStyle}"
CornerRadius="3" />
<ContentPresenter />
</Grid>
</UserControl>
Sample usage of this UserControl:
<nc:ExpanderPanel
Grid.Row="0">
<Expander
IsExpanded="True"
Header="NMT Users">
<StackPanel>
...
</StackPanel>
</Expander>
</nc:ExpanderPanel>
Discussion
If I run this, I see nothing. No content is presented, not even the border that is built into the UserControl.
I thought maybe I needed to make the ContentPresenter a dependency property, but I couldn't figure out how I would link the property to the ContentPresenter in the UserControl's XAML.
Can someone provide a simple example that shows how to build a UserControl (or some kind of custom control) with a single ContentPresenter?
ContentPresenters are main used in ControlTemplates and bound with a TemplateBinding to the ContentControl.Content.
from this site... a control template for a button that uses a ContentPresenter
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Rectangle Fill="{TemplateBinding Property=Background}" />
<ContentPresenter
Content="{TemplateBinding Property=ContentControl.Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources