TemplateBinding a Title in custom window template WPF - wpf

So I'm making a custom window template for my WPF application. The trouble I'm having is that I cannot access the Window Title property inside the template.
I tried this:
<TextBlock Text="{TemplateBinding Title}" />
And this:
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}" />
Everything that I've read indicates that either of those two should work and yet the text is never set.
Any suggestions?
EDIT: Presenting the entire style xaml
<Style x:Key="RegularWindow" TargetType="{x:Type Window}">
<Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="10" Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{TemplateBinding Title}" FontWeight="Bold" Grid.Row="0" />
<AdornerDecorator Grid.Row="1">
<ContentPresenter/>
</AdornerDecorator>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

So it turns out that Expression Blend fails to render the window correctly. As soon as I run the code it actually works. My bad for trusting Expression Blend.

Related

DatePicker template, borders appear on mouse over

I have a weird problem,
My DatePicker shows in the middle some borders. I don't know where it comes from.
I changed every property of the DatePickerTextBox but it doesn't change anything.
Here is the XAML :
<Window.Resources>
<Style TargetType="{x:Type DatePicker}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePicker}">
<Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="5">
<Grid x:Name="PART_Root" Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<DatePickerTextBox x:Name="PART_TextBox"
BorderThickness="0"
BorderBrush="Transparent"
HorizontalContentAlignment="Stretch"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="Center"
Visibility="Visible"
SelectionBrush="#FF6F5DF5"
FocusVisualStyle="{x:Null}"
Grid.Column="0" Margin="0,3,0,0">
<DatePickerTextBox.Style>
<Style>
<Setter Property="TextBox.BorderThickness" Value="0"/>
</Style>
</DatePickerTextBox.Style>
</DatePickerTextBox>
<Button x:Name="PART_Button" HorizontalAlignment="Right" Margin="0,0,0.333,0.333" Width="24">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Image Source="Resources/Images/down.png"></Image>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<Popup x:Name="PART_Popup" StaysOpen="False" AllowsTransparency="True" Margin="0,0,0.333,0.333" />
<Label x:Name="lblLabel" Content="{TemplateBinding Uid}" HorizontalContentAlignment="Center" Foreground="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="0" Padding="12,0" FontFamily="Poppins" VerticalContentAlignment="Stretch" Margin="6,-11,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDropDownOpen" Value="True">
<Setter TargetName="MainBorder" Property="BorderBrush" Value="#FF6F5DF5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainBorder" Property="BorderBrush" Value="#FF6F5DF5"/>
<Setter TargetName="PART_TextBox" Property="BorderThickness" Value="0"/>
<Setter Property = "BorderBrush" Value="{Binding ToYourBorder}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<DatePicker Margin="10,260,0,0" VerticalAlignment="Top" Uid="Date de naissance *" FontSize="12" Height="40" BorderThickness="0" HorizontalAlignment="Left" Width="181" FontFamily="Poppins" Background="#FFFEFEFE" BorderBrush="#FF9A9A9A" Foreground="#FF727272" />
And here how it seems :
And on hover, there is another thin border inside :
Any idea, please?
DatePickerTextBox has it's own Template where the border and the triggers for the border are defined/hardcoded.
You need to take care of those in the template of DatePickerTextBox.
Change:
<DatePickerTextBox.Style>
<Style>
<Setter Property="TextBox.BorderThickness" Value="0"/>
</Style>
</DatePickerTextBox.Style>
To:
<DatePickerTextBox.Style>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox" BorderThickness="0"
Text="{Binding Path=SelectedDate, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePickerTextBox.Style>
And it should work.
For a complete Template see DOCS

Xaml switch between TextBlock and TextBox

I've noticed that TextBoxes are very slow and create performance issues when the Text is changed dynamically by code (I need to change the Text continuosly to 10-15 TextBoxes at the same time), so, as a workaround, I've created a custom control with a TextBlock and a TextBox:
The TextBlock is used in almost all time.
The TextBox is used only when I need to edit the Text inside the control with keyboard.
My solution is to change the template and use the TextBox when the control is focused:
(Value is a string Dependency Property)
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Value" Value="Val"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Value}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBox HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Text="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
But when I click on the control nothing happens.
I think that the problem is that the "focus state" is passed to the internal TextBox, and the control loses the "focus state".
There is a better way to create a custom "TextBox" control like this, or a way to resolve this problem?
You don't need a custom control for this, that's just adding unnecessary overhead. What you're trying to create is still a TextBox, with all the usual behavior of a TextBox (focus etc). All you need to do is change the template to a TextBlock when it's not in focus:
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<TextBlock Text="{TemplateBinding Text}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<TextBox Text="Hello World" />
<TextBox Text="Goodbye World" />
</StackPanel>

WPF - changing title of window with accessing to the title of Style [duplicate]

So I'm making a custom window template for my WPF application. The trouble I'm having is that I cannot access the Window Title property inside the template.
I tried this:
<TextBlock Text="{TemplateBinding Title}" />
And this:
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}" />
Everything that I've read indicates that either of those two should work and yet the text is never set.
Any suggestions?
EDIT: Presenting the entire style xaml
<Style x:Key="RegularWindow" TargetType="{x:Type Window}">
<Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="10" Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{TemplateBinding Title}" FontWeight="Bold" Grid.Row="0" />
<AdornerDecorator Grid.Row="1">
<ContentPresenter/>
</AdornerDecorator>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So it turns out that Expression Blend fails to render the window correctly. As soon as I run the code it actually works. My bad for trusting Expression Blend.

Creating tabs at the bottom of a LayoutDocument in AvalonDock 2.0?

How can I create tabs (in XAML) at the bottom of a LayoutDocument in AvalonDock 2.0, like the Code and Design tabs in Visual Studio? (without using a TabControl, of course)
I'd like to end up with tabs at the top, one per document, but then within each document, be able to have multiple "views," with one tab each, at the bottom of the window.
So, you might have "page.htm" as one document, appearing on a tab at the top. Then "source" and "design" as two tabs at the bottom of the open/activated document.
You sould override the default style of the LayoutDocumentPaneControl and for this I'd suggest to take look at one of the provided theme.
Sample code (not tested):
<!--MyCustomDocumentPaneControlStyle-->
<Style x:Key="MyCustomDocumentPaneControlStyle" TargetType="{x:Type avalonDockControls:LayoutDocumentPaneControl}">
<Setter Property="TabStripPlacement" Value="Bottom"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentPaneControl}">
<Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Following border is required to catch mouse events-->
<Border Background="Transparent" Grid.RowSpan="2"/>
<Grid Panel.ZIndex="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<avalonDockControls:DocumentPaneTabPanel x:Name="HeaderPanel" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1"/>
<avalonDockControls:DropDownButton
x:Name="MenuDropDownButton"
Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}"
Focusable="False"
Grid.Column="1">
<avalonDockControls:DropDownButton.DropDownContextMenu>
<avalonDockControls:ContextMenuEx
ItemsSource="{Binding Model.ChildrenSorted, RelativeSource={RelativeSource TemplatedParent}}">
<avalonDockControls:ContextMenuEx.ItemContainerStyle>
<Style TargetType="{x:Type avalonDockControls:MenuItemEx}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Setter Property="HeaderTemplate" Value="{Binding Path=Root.Manager.DocumentPaneMenuItemHeaderTemplate}"/>
<Setter Property="HeaderTemplateSelector" Value="{Binding Path=Root.Manager.DocumentPaneMenuItemHeaderTemplateSelector}"/>
<Setter Property="IconTemplate" Value="{Binding Path=Root.Manager.IconContentTemplate}"/>
<Setter Property="IconTemplateSelector" Value="{Binding Path=Root.Manager.IconContentTemplateSelector}"/>
<Setter Property="Command" Value="{Binding Path=., Converter={StaticResource ActivateCommandLayoutItemFromLayoutModelConverter}}"/>
</Style>
</avalonDockControls:ContextMenuEx.ItemContainerStyle>
</avalonDockControls:ContextMenuEx>
</avalonDockControls:DropDownButton.DropDownContextMenu>
<Image Source="/AvalonDock;component/Images/PinDocMenu.png"/>
</avalonDockControls:DropDownButton>
</Grid>
<Border x:Name="ContentPanel"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Grid.Column="0"
KeyboardNavigation.DirectionalNavigation="Contained"
Grid.Row="0"
KeyboardNavigation.TabIndex="2"
KeyboardNavigation.TabNavigation="Cycle">
<ContentPresenter x:Name="PART_SelectedContentHost"
ContentSource="SelectedContent"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Model.ChildrenCount}" Value="0">
<Setter Property="Visibility" Value="Collapsed" TargetName="MenuDropDownButton" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="ToolTip" Value="{Binding ToolTip}"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<avalonDockControls:LayoutDocumentTabItem Model="{Binding}"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<avalonDockControls:LayoutDocumentControl Model="{Binding}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
As you have the new style just plug it using the DocumentPaneControlStyle property of the DockingManager:
<ad:DockingManager DocumentPaneControlStyle="{StaticResource MyCustomDocumentPaneControlStyle}">
...
</ad:DockingManager>
Ado

Trigger in template causes wrong rendering

I'm implementing my own fake TabControl to look like IE8-tabs (I'm aware of other implementations of tabcontrol).
My TabControl derives from Selector, and my TabItems derive from ContentControl.
When a tab is selected I set IsSelected (a dependencyproperty) to true.
My Trigger looks like this:
<Trigger Property="IsSelected" Value="true">
<Setter Property="Margin" Value="0,0,0,0"/>
</Trigger>
The default margin for my TabItem is 0,2,0,0. In other words, unselected TabItems should have a slight offset to the selected.
I've tried doing this in reverse, and using height instead. The result is that TabItems that are selected seems to be clipped instead of altering the margin.
I get the correct visual when the property is set on the tag directly, i.e.:
<local:TabItem IsSelected="true"/>
I've tried invalidating Arrange, Visual and Measure in my IsSelected dependency property without much success.
What am I missing here?
Edit:
Here's the complete style for the TabItem (the style is partly based on this project: http://www.codeproject.com/KB/WPF/WpfTabControl.aspx):
<Style TargetType="{x:Type local:TabItem}">
<Setter Property="Background" Value="{Binding Path=TabItemNormalBackground, RelativeSource={RelativeSource Self}}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Height" Value="26"/>
<Setter Property="Margin" Value="0,2,0,0"/>
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TabItem}">
<Border CornerRadius="3,3,0,0"
Background="{TemplateBinding Background}"
BorderBrush="{StaticResource TabItemOuterBorderBrush}"
BorderThickness="1,1,1,0">
<Border CornerRadius="3,3,0,0"
Background="{TemplateBinding Background}"
BorderBrush="{StaticResource TabItemInnerBorderBrush}"
BorderThickness="1,1,1,0">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" Content="{TemplateBinding Icon}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<ContentPresenter Grid.Column="1"
SnapsToDevicePixels="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
<Button x:Name="PART_CloseButton"
Grid.Column="2"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="5,0,5,0"
Style="{StaticResource CloseButtonStyle}"
Visibility="Collapsed"
/>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="{Binding Path=TabItemSelectedBackground, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Margin" Value="0,0,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Nevermind. I stored the tabitems desiredsize in MeasureOverride, and forgot to clear them in subsequent calls.

Resources