wpf Control Template not working at runtime - wpf

After creating ControlTemplate for Wpf window it's working fine in design view. But when I run, it does not show the outer red border.
here is my code
<Window x:Class="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"
WindowStyle="None"
AllowsTransparency="True"
WindowStartupLocation="CenterScreen"
>
<Window.Resources>
<Style TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Border Padding="20" Background="red">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome
ResizeBorderThickness="10"
CaptionHeight="40"
CornerRadius="0"
GlassFrameThickness="0"
/>
</WindowChrome.WindowChrome>
<Grid>
<Border Background="Black" Padding="20">
<Button Content="ok"/>
</Border>
</Grid>
</Window>
The outer red border not showing when I run it. Can anyone tell me if I made any mistake?

At runtime, your window's type is MainWindow, not Window, hence the Style does not apply.
You may change the Style's TargetType to MainWindow:
<Window xmlns:local="clr-namespace:YourNamespace" ...>
<Window.Resources>
<Style TargetType="local:MainWindow">
...
</Style>
</Window.Resources>
...
</Window>
Or set the Window's Style property directly:
<Window ...>
<Window.Style>
<Style TargetType="Window">
...
</Style>
</Window.Style>
...
</Window>
Or set only the Template property directly:
<Window ...>
<Window.Template>
<ControlTemplate TargetType="Window">
<Border Padding="20" Background="red">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</Window.Template>
...
</Window>

Just making small change it worked fine for me
<Window.Resources>
<Style TargetType="local:MainWindow">
<Setter Property="Template">
...
</Style>
</Window.Resources>

Related

Border style based on standard control causing runtime error

I created a new WPF project by Blend 2017 (.net 4.7) with one window and this Xaml (added no code behind):
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<Style x:Key="_borderStyleWithChildBinding"
TargetType="{x:Type Border}"
BasedOn="{StaticResource {x:Type Border}}">
<Setter Property="BorderBrush"
Value="{Binding RelativeSource={RelativeSource Self}, Path=Child.Fill}" />
</Style>
</Window.Resources>
<Grid Width="50"
Height="30"
Margin="10">
<Border BorderThickness="5"
Style="{StaticResource _borderStyleWithChildBinding}">
<Border.Child>
<Rectangle Width="20"
Height="10"
Fill="Green" />
</Border.Child>
</Border>
</Grid>
</Window>
It compiles but reports a runtime error concerning line
BasedOn="{StaticResource {x:Type Border}}"
Exception: System.Windows.Markup.XamlParseException: A value for System.Windows.Markup.StaticResourceHolder caused an exception.
InnerException: Resource System.Windows.Controls.Border cannot be found.
The designer is smart enough to show the right thing:
We can solve the problem by omitting the x:Key and the BasedOn property of the border style:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<Style TargetType="{x:Type Border}" >
<Setter Property="BorderBrush"
Value="{Binding RelativeSource={RelativeSource Self}, Path=Child.Fill}" />
</Style>
</Window.Resources>
<Grid Width="50"
Height="30"
Margin="10">
<Border BorderThickness="5">
<Border.Child>
<Rectangle Width="20"
Height="10"
Fill="Green" />
</Border.Child>
</Border>
</Grid>
</Window>

WPF Style Sheets and Bindings

I have a style sheet that i want to be used on different custom controls.
Example
Stylesheet.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ExampleProgressBar" TargetType="ProgressBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border DataContext="{Binding RelativeSource={RelativeSource Self}}" Background="{Binding Path=Example_BG}">
<Grid x:Name="PART_Track" >
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" Fill="#FF1B9AF1" RadiusX="5" RadiusY="5"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
When I use something like above on the style sheet it doesn't bind to the custom control....
Is there anyway to bind stylesheet styles to work with many custom controls?

How to disable (globally) the FocusVisualStyleKey

I want to disable (globally) the FocusVisualStyleKey.
I'm looking for a possibility, that I have not put on any element the following code:
<Style TargetType="ToggleButton">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
So I read this article, and found this solution:
App.xaml
<Application x:Class="WpfApplication7.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="{x:Static SystemParameters.FocusVisualStyleKey}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeThickness="0" SnapsToDevicePixels="true" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
MainWindow.xaml
<Window x:Class="WpfApplication7.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>
</Window.Resources>
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="98,230,0,0" VerticalAlignment="Top" Width="75"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="217,230,0,0" VerticalAlignment="Top" Width="75"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="368,230,0,0" VerticalAlignment="Top" Width="75"/>
<ComboBox HorizontalAlignment="Left" Margin="40,40,0,0" VerticalAlignment="Top" Width="150" Height="40"/>
<ComboBox HorizontalAlignment="Left" Margin="317,40,0,0" VerticalAlignment="Top" Width="150" Height="40"/>
</Grid>
</Window>
But it doesn't work...
Does anyone have another idea?
Yes, there is a way to do this but you are not going to like it. First make another xaml dictionary. In it define a style for each control in Aero or w/e theme you're using, then set BasedOn property to implicit key.
example
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
then create a setter for FocusVisualStyle
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
</Style>
Note: you'll have to do this for EVERY control.
Next merge your new themes dictionary into Window.Resources
<Window.Resources>
<ResourceDictionary Source="[your dictionary]"/>
</Window.Resources>

How to style WPF tooltip like a speech bubble?

I want to shape my WPF tooltip like the image below:
How do I achieve this?
Use this Code:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480">
<Window.Resources>
<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<ed:Callout Name="Border"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
MinWidth="100"
MinHeight="30"
Margin="0,0,0,50"
AnchorPoint="0,1.5"
Background="{StaticResource LightBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1"
CalloutStyle="RoundedRectangle"
Fill="#FFF4F4F5"
FontSize="14.667"
Stroke="Black">
<ContentPresenter Margin="4"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</ed:Callout>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button ToolTip="Hello" />
</Grid>
this is the begining, now you have to play with it... enjoy!

Understanding how styling and templating work in Silverlight

I'm trying to understand how styles works in silverlight, this is what I've done :
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<vm:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="test.png" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100 />
</StackPanel>
The text and the image are displayed correctly, note that test.png is a resource file at the root of my projet.
First thing I don't understand : why is my image correctly displayed at runtime, but not at design in visual studio ?
Then, I would like to use a databinded value in my style, so I use :
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<vm:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="{Binding MyUrl}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100" />
</StackPanel>
Ok, it's working, my viewmodel exposes an Uri with the test.png as relative.
What I would like to do now is to use the button with many images, so it could have been great to be able to do something like this :
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:SilverlightApplication1" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<vm:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="{TemplateBinding TheUrl}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100" TheUrl="{Binding MyUrl}" />
</StackPanel>
but the property TheUrl of course doesn't exists in the button.
I don't want to create my own control, the purpose is to understand styles.
How can I do this ?
Thanks in advance for any help.
Best regards
you are correct in your observation that button does not have a TheUrl property. You have to options here. One is to use the Tag property of Button:
<UserControl.Resources>
<Style x:Key="TestStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="{TemplateBinding Tag}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="{Binding SayHello}" />
<Button Style="{StaticResource TestStyle}" Width="100" Height="100" Tag="{Binding MyUrl}" />
</StackPanel>
As an aside, I would not bind to the Width / Height properties, these may not be set explicitly. Instead, bind to ActualHeight and ActualWidth which you can guarantee will always be set.
Tag is a property of type object which can be used for general extensibility. The other, more elegant option is to define an attached property. See the tutorial in the following blog post:
http://www.hardcodet.net/2009/01/create-wpf-image-button-through-attached-properties

Resources