I have a custom template for my application Windows that I have built. It's in App.xaml
<Application.Resources>
<ResourceDictionary>
<Style x:Key="XWindow" TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate >
<Border BorderThickness="3">
<Border.Effect>
<DropShadowEffect BlurRadius="5" Direction="270" RenderingBias="Quality" ShadowDepth="0.5" Opacity="0.8" Color="#FF00B9FF"/>
</Border.Effect>
<Grid Background="White">
<local:ControlButtons Height="38" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<Border BorderBrush="#99007CF7" BorderThickness="1"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
In my MainWindow.xaml I have applied this style like this (and it works) : <Window [...] Style="{DynamicResource XWindow }"
So the style is applied to the window. But when I put a control in the Window, I cannot see it or even select it. It's in the XAML code but even when I debug it's not on the Window.. Anyone has a clue ?
There's a screenshot :
XAML Problem
This is what it should normally do when I add a simple button : XAML Norrmal
As pointed out by #Clemens you have forgotten to add a ContentPresenter to your ControlTemplate. This is where the actual content of the window will be displayed.
You should also remember to put the ContentPresenter in an AdornedDecorator:
<Style x:Key="XWindow" TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border BorderThickness="3">
<Border.Effect>
<DropShadowEffect BlurRadius="5" Direction="270" RenderingBias="Quality" ShadowDepth="0.5" Opacity="0.8" Color="#FF00B9FF"/>
</Border.Effect>
<Grid Background="White">
<local:ControlButtons Height="38" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<Border BorderBrush="#99007CF7" BorderThickness="1">
<AdornerDecorator>
<ContentPresenter/>
</AdornerDecorator>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The AdornedDecorator specifies the position of the AdornerLayer in the visual tree as stated on MSDN here: http://msdn.microsoft.com/en-us/library/system.windows.documents.adornerdecorator.aspx. You will for example need one if you intend to dipslay any validation errors in your window as validation errors are displayed on the adorner layer.
Edit: You should also set the TargetType property of the ControlTemplate:
<ControlTemplate TargetType="{x:Type Window}">
Related
I just have a simple binding, it works well but there is an error popup.
The effects work but still an error.
And the error is
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is 'VisualBrush' (HashCode=23487194); target property is 'Visual' (type 'Visual')
I have tried x: Reference but there would be another error.
Appreciated a lot if any can help.
<Style TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border
x:Name="RoundMask"
CornerRadius="10"
Background="white"/>
<!-- The main content -->
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=RoundMask}" />
</Grid.OpacityMask>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Re templating a window like that is not really the way I'd go about this sort of thing.
I'd use something more like the approach in this sample:
https://gallery.technet.microsoft.com/ThWPFPolishing-Chrome-f41be7fe
Finished fancy window is
Window6, using WindowChrome styling which is in the resource dictionary Dictionary1.
Which has stuff lika a big round close button. But to give you the idea before downloading:
<Style x:Key="FinishedWindow" TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="Foreground" Value="{StaticResource DarkDark}"/>
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="0"
CornerRadius="20"
GlassFrameThickness="0"
NonClientFrameEdges="None"
ResizeBorderThickness="5"
/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border Background="{StaticResource BrightMid}" BorderBrush="{StaticResource DarkLight}" BorderThickness="4,4,6,6"
CornerRadius="12">
<Border.Effect>
<BlurEffect KernelType="Gaussian" Radius="12" RenderingBias="Quality" />
</Border.Effect>
</Border>
<Border BorderBrush="{StaticResource DarkDark}" BorderThickness="2"
CornerRadius="12" ClipToBounds="True">
</Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}"
Foreground="{StaticResource DarkDark}"
Grid.Row="0"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
FontWeight="Bold"
FontSize="16"
/>
<Button Name="CloseButton"
Width="20" Height="20"
Grid.Row="0"
HorizontalAlignment="Right"
BorderThickness="0"
Margin="0,12,12,0"
Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CloseCommand}"
Style="{StaticResource CloseButton}"/>
<ContentPresenter Grid.Row="1" Margin="12"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
I gave your style a go.
Just using it implicitly had no effect at all.
I put it in app.xaml and gave it a key
<Application.Resources>
<Style TargetType="{x:Type Window}" x:Key="roundedWindowStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border
x:Name="RoundMask"
CornerRadius="10"
Background="white"/>
<!-- The main content -->
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=RoundMask}" />
</Grid.OpacityMask>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And then I applied that to mainwindow
<Window
...
Title="MainWindow"
Style="{StaticResource roundedWindowStyle}"
Hit f5... and it kind of works. Well.
If you ignore that window chrome means it cannot work as you seem to intend.
You probably ought to be looking at using window chrome instead.
With what you have there.
At the absolute minimum, you need a Contentpresenter inside that Grid.
Because a window is a content control but it won't show any content at all if you have no contentpresenter in the template.
I'm using the TextBox below, which in order to apply a DropShadowEffect on its text, uses a ControlTemplate. I managed to get the TextWrapping to work, but once the TextBox fills up, it's content goes out of view. How do I replicate the Auto scrolling to the bottom feature of a native TextBox?
<TextBox TextWrapping="Wrap"
Foreground="LimeGreen"
Background="Black"
Margin="10,40,10,40"
FontSize="40"
HorizontalAlignment="Stretch"
x:Name="Inp"
FontFamily="Courier New"
CaretBrush='LimeGreen'>
<TextBox.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid x:Name="RootElement">
<ScrollViewer>
<ContentPresenter Content="{TemplateBinding Text}">
<ContentPresenter.Effect>
<DropShadowEffect ShadowDepth="4"
Direction="330"
Color="LimeGreen"
Opacity="1"
BlurRadius="5" />
</ContentPresenter.Effect>
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property='TextWrapping'
Value='Wrap' />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Resources>
</TextBox>
This solution is a bit different that what you might expect. I think using the ContentPresenter is the wrong way because in the end you still want the functionality of the TextBox. So my solution focuses on getting rid of the border and focus indicator that mess up the drop shadow effect:
<TextBox x:Name="Inp"
Height="100"
HorizontalAlignment="Stretch"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
CaretBrush="LimeGreen"
FontFamily="Courier New"
FontSize="40"
Foreground="LimeGreen"
TextWrapping="Wrap">
<TextBox.Effect>
<DropShadowEffect BlurRadius="5"
Direction="330"
Opacity="1"
ShadowDepth="4"
Color="LimeGreen" />
</TextBox.Effect>
<TextBox.FocusVisualStyle>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate/>
</Setter.Value>
</Setter>
</Style>
</TextBox.FocusVisualStyle>
</TextBox>
I set the Background, BorderBrush to be transparent (=> no shadow). I removed the ContentPresenter; it's a 'regular textbox now. And to remove the focus border I set the FocusVisualStyle to an empty Template.
I have a Viewbox:
<Viewbox x:Key="SampleViewbox" >
<Grid>
<Ellipse Stroke="#e2e2e0" StrokeThickness="6" Fill="#d5273e" Width="128" Height="128"/>
</Grid>
</Viewbox>
I then include this in a Style like:
<Style x:Key="SampleStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="Transparent" >
<ContentPresenter Content="{StaticResource SampleViewbox}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I created many buttons with SampleStyle
<Grid>
<StackPanel>
<Button Style="{StaticResource SampleStyle}" Height="50" Width="50"></Button>
<Button Style="{StaticResource SampleStyle}" Height="80" Width="80"></Button>
<Button Style="{StaticResource SampleStyle}" Height="20" Width="20"></Button>
</StackPanel>
</Grid>
However, Only one button has the Ellipse (viewbox)
How can I make all the buttons have/show the ellipse??
Viewbox is FrameworkElement which cannot belong to multiple parents. Every time buttons request a resource {StaticResource SampleViewbox} they get the same instance.
to change that behavior add x:Shared="False" attribute
<Viewbox x:Key="SampleViewbox" x:Shared="False">
I think a good approach is to use DataTemplate.
So you will have
<DataTemplate x:Key="SampleViewbox">
<Viewbox>
<Grid>
<Ellipse
Width="128"
Height="128"
Fill="#d5273e"
Stroke="#e2e2e0"
StrokeThickness="6" />
</Grid>
</Viewbox>
</DataTemplate>
And for style
<Style x:Key="SampleStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="Transparent">
<ContentPresenter ContentTemplate="{StaticResource SampleViewbox}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Setting the x:Shared attribute of the ViewBox to false as suggested by #ASh will indeed work but why don't you just include the ViewBox in the ControlTemplate like this?
<Style x:Key="SampleStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="Transparent" >
<Viewbox>
<Grid>
<Ellipse Stroke="#e2e2e0" StrokeThickness="6" Fill="#d5273e" Width="128" Height="128"/>
</Grid>
</Viewbox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
A template is a template and a control instance is an instance.
I'm having troubles with the Window icon.
I've created my own Style for the Windows that is contained in a .xaml file inside the project. What I would like to do is to show the system Icon at the left corner of the Window. Usually, working directly on the Window I can set the Icon specifing it in the Icon property. But it's not working because the Window uses my own Style where the icon is not defined. So I tried to add the Setter for the Icon property inside my style:
<Style x:Key="KavoWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="30"
GlassFrameThickness="0"
CornerRadius="0"
NonClientFrameEdges="None"
ResizeBorderThickness="5"
UseAeroCaptionButtons="False"/>
</Setter.Value>
</Setter>
<Setter Property="Icon" Value="MyIcon.ico"/> <==================
<Setter Property="BorderBrush" Value="#2ECC71"/>
<Setter Property="Background" Value="#646464"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<AdornerDecorator>
<ContentPresenter/>
</AdornerDecorator>
</Border>
<DockPanel Height="30"
VerticalAlignment="Top"
LastChildFill="False">
<TextBlock VerticalAlignment="Center"
DockPanel.Dock="Left"
Margin="5,0,0,0"
FontSize="14"
Foreground="#E8E8E8"
Text="{TemplateBinding Title}"
FontFamily="Open Sans Regular"/>
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But it's not working (I get an exception when I run the program). I don't know if this is the right way to do it, and if not, I would like to know what is the right approach. Thank you in advance!
You have to place the icon somewhere in your custom title bar.
For example you can put an Image left of your TextBlock:
<DockPanel Height="30"
VerticalAlignment="Top"
LastChildFill="False">
<Image Source="{TemplateBinding Icon}" />
<TextBlock VerticalAlignment="Center"
DockPanel.Dock="Left"
Margin="5,0,0,0"
FontSize="14"
Foreground="#E8E8E8"
Text="{TemplateBinding Title}"
FontFamily="Open Sans Regular"/>
</DockPanel>
Now it should be shown. Please adapt the size and layout to fit your needs.
I have a requirement to create a WPF TabControl control with tabs rotated to the left.
The resources I've found online suggest that this can be done by applying the following two things to the TabControl:
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270"/>
</Setter.Value>
</Setter>
and
<TabControl TabStripPlacement="Left" ...
All this works and the tabs are displayed as required but for some reason the Header text in the tabs appears blurry after the rotation, please suggest why this is happening and if there is anything I can do to fix this issue.
Complete XAML:
<Window x:Class="WpfApplication2.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">
<Grid>
<TabControl BorderBrush="Gray" BorderThickness="1" TabStripPlacement="Left">
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" BorderBrush="Gray" BorderThickness="1" CornerRadius="6,6,0,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center" HorizontalAlignment="Center"
ContentSource="Header" Margin="12,2,12,2"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
<TabItem Header="Item 1" />
<TabItem Header="Item 2" />
<TabItem Header="Item 3" />
</TabControl>
</Grid>
</Window>
Add the following properties to the window declaration XAML
TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="ClearType"
UseLayoutRounding="true"
You could check out the RenderOptions class which controls rendering behavior of Objects. For example see this (Image in WPF getting Blurry) where it was used to reduce blurring of images.
Try to add SnapsToDevicePixels="True" and UseLayoutRounding="True" to your Border or TabControl tag. These have solved my blurriness problems in most cases.
I suggest this code snippet :
<TabControl TabStripPlacement="Left" Margin="5" FontSize="13" FontFamily="Verdana" Grid.ColumnSpan="2" SnapsToDevicePixels="True" UseLayoutRounding="True" >
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="grid" Margin="0" >
<Border.LayoutTransform>
<RotateTransform Angle="270" ></RotateTransform>
</Border.LayoutTransform>
<ContentPresenter>
<ContentPresenter.Content>
<TextBlock FontFamily="Verdana" Margin="4" Text="{TemplateBinding Content}">
</TextBlock>
</ContentPresenter.Content>
</ContentPresenter>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Name="General" Header="YourHeader" > ..