I am using MahApps.Metro in my WPF app. The default behavior of the title bar of its MetroWindow is that any icon inside it has low opacity (dimmed) display unless you mouseover the icon. Even if you don't mouseover the icon, I would like to look it the same as when you mouseover it. How can we achieve this?
With mouseover on CupCakes icon [I would like it to look the same even without mouseover]:
Without mouseover:
MetroWindow.xaml:
<mah:MetroWindow x:Class="WPF_Mah_Metro_Test.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:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Mah_Metro_Test"
mc:Ignorable="d"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
Height="450" Width="800">
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands>
<Button x:Name="btnTest" Click="btnTest_Click" ToolTip="Open up the GitHub site">
<iconPacks:PackIconModern Width="22" Height="22" Kind="SocialGithubOctocat" />
</Button>
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands>
<Button x:Name="btnTest1" Click="btnTest1_Click" Content="Deploy CupCakes">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconModern Width="22" Height="22" VerticalAlignment="Center" Kind="FoodCupcake" />
<TextBlock Margin="4 0 0 0" VerticalAlignment="Center" Text="{Binding}" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
<Grid>
</Grid>
</mah:MetroWindow>
To override the styles of the inner controls of the WindowCommands you must create your own style for it:
<Style x:Key="Styles.WindowCommands.Custom"
BasedOn="{StaticResource MahApps.Styles.WindowCommands}"
TargetType="{x:Type mah:WindowCommands}">
<Style.Resources>
<ResourceDictionary>
<Style BasedOn="{StaticResource MahApps.Styles.Button.WindowCommands}" TargetType="{x:Type Button}">
<Setter Property="Opacity" Value="1" />
</Style>
<Style BasedOn="{StaticResource MahApps.Styles.ToggleButton.WindowCommands}" TargetType="{x:Type ToggleButton}">
<Setter Property="Opacity" Value="1" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
<Style BasedOn="{StaticResource MahApps.Styles.SplitButton.WindowCommands}" TargetType="{x:Type mah:SplitButton}">
<Setter Property="Opacity" Value="1" />
</Style>
<Style BasedOn="{StaticResource MahApps.Styles.DropDownButton.WindowCommands}" TargetType="{x:Type mah:DropDownButton}">
<Setter Property="Opacity" Value="1" />
</Style>
</ResourceDictionary>
</Style.Resources>
</Style>
Now if you put this key to your `App.xaml you can use it in your App like:
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands Style="{StaticResource Styles.WindowCommands.Custom}">
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands Style="{StaticResource Styles.WindowCommands.Custom}">
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
Another solution could be to make a style for the Button directly.
Note: Namespace for mah is xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
Related
For two TabItems I have two Styles, both use the same ControlTemplate. Now I want styleTabB to show a yellow underline instead of green, but still using the ControlTemplate. How can I modify the Style to accomplish this?
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" FontSize="16">
<Window.Resources>
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
<Grid>
<TextBlock Name="tbTabItemHeaderText"
Text="{TemplateBinding Header}"
Grid.Column="0"
Background="Thistle"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="3,0,0,3">
<TextBlock.TextDecorations>
<TextDecorationCollection>
<TextDecoration Location="Underline"
PenThicknessUnit="Pixel"
PenOffsetUnit="Pixel"
PenOffset="2">
<TextDecoration.Pen>
<Pen Brush="Green" Thickness="4" />
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</TextBlock.TextDecorations>
</TextBlock>
</Grid>
</ControlTemplate>
<!-- Style Tab A -->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!-- Style Tab B -->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
</Window.Resources>
<Grid>
<TabControl Name="tabControl">
<TabItem Name="tabItem_1" Header="--- Tab A ---" Style="{StaticResource styleTabA}"/>
<TabItem Name="tabItem_2" Header="--- Tab B ---" Style="{StaticResource styleTabB}" />
</TabControl>
</Grid>
</Window>
UPDATE
I tried the proposal of Chris W., but no underline at all is shown:
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
...
<TextDecoration.Pen>
<Pen Brush="{TemplateBinding Tag}" Thickness="4" />
</TextDecoration.Pen>
...
</ControlTemplate>
<!--Style Tab A-->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Green" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!--Style Tab B-->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
You can set the style of the children within the child by targetting particular types. Here all Pen are updated with Yellow color.
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Style.Resources>
<Style TargetType="{x:Type Pen}">
<Setter Property="Brush" Value="Yellow"></Setter>
</Style>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
#CarbineCoder is correct for most instances but for your instance you're right and the error you received from his would be expected since Pen isn't a TargetType. However if we tweak it just a little to hit the actual FrameworkElement of which TextDecorations is a property let's try this...and read the whole thing since the first snippet is just an example explanation.
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextDecorations">
<Setter.Value>
<TextDecorationCollection>
<TextDecoration>
<TextDecoration.Pen>
<Pen Brush="Yellow"/>
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
** *Except that's not going to work because you're hoping for something that you've already provided an explicit property value for to inherit from parent, and it doesn't work that way. How about instead we bring in the handy Tag property (which I abuse all the time) to piggy back in our value and allow a way to talk to our buddy on the inside of that bugger by making some quick edits to your ControlTemplate like;
<!-- In your STYLE Template you would want to add a default setter of;
<Setter Property="Tag" Value="Green"/>
-->
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
<Grid Margin="0,0,0,0">
<TextBlock Name="_tbTabItemHeaderText"
Text="{TemplateBinding Header}"
Grid.Column="0"
Background="Thistle"
VerticalAlignment="Center"
Margin="3,0,0,3">
<TextBlock.TextDecorations>
<TextDecorationCollection>
<TextDecoration Location="Underline"
PenThicknessUnit="Pixel"
PenOffsetUnit="Pixel"
PenOffset="2">
<TextDecoration.Pen>
<Pen Brush="{TemplateBinding Tag}" Thickness="4" />
</TextDecoration.Pen>
</TextDecoration>
</TextDecorationCollection>
</TextBlock.TextDecorations>
</TextBlock>
</Grid>
</ControlTemplate>
Now we should be able to hit like;
<!-- Style Tab A
: This guy should just keep it green IF you applied the default setter mentioned above to the STYLE template -->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!-- Style Tab B
: This guy should turn it Yellow -->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow"/>
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
I didn't have time to test, but it seems like this should work fine for your scenario. Hope it helps.
I made a little change on Chris W.'s solution and now it's working:
<ControlTemplate x:Key="ctrlTemplate" TargetType="{x:Type TabItem}">
...
<TextDecoration.Pen>
<!--Changed next line from <Pen Brush="{TemplateBinding Tag}" Thickness="4" /> to:-->
<Pen Brush="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Thickness="4" />
</TextDecoration.Pen>
...
</ControlTemplate>
<!--Style Tab A-->
<Style x:Key="styleTabA" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Green" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
<!--Style Tab B-->
<Style x:Key="styleTabB" TargetType="{x:Type TabItem}">
<Setter Property="Tag" Value="Yellow" />
<Setter Property="Template" Value="{StaticResource ctrlTemplate}" />
</Style>
I've got the below style for TextBoxes in my WPF app:
<!-- http://www.thexamlproject.com/ -->
<Style x:Key="LockIcon" TargetType="Path">
<Setter Property="Height" Value="16" />
<Setter Property="Width" Value="16" />
<Setter Property="Stretch" Value="Uniform" />
<Setter Property="Data"
Value="F1 M 80.6667,55.1172L 80.6667,35.3333C 80.6667,15.851 64.815,3.05176e-005 45.3333,3.05176e-005C 25.8509,3.05176e-005 9.99998,15.851 9.99998,35.3333L 9.99998,55.1172L 0,56L 0,129.333L 45.3333,133.333L 90.6667,129.333L 90.6667,56L 80.6667,55.1172 Z M 20.6667,54.1771L 20.6667,35.3333C 20.6667,21.7318 31.7317,10.6667 45.3333,10.6667C 58.9349,10.6667 70,21.7318 70,35.3333L 70,54.1771L 45.3333,52L 20.6667,54.1771 Z " />
</Style>
<VisualBrush x:Key="LockBrush" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<Border BorderThickness="4" BorderBrush="Transparent">
<Path Style="{StaticResource LockIcon}" Fill="Red" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" Value="{StaticResource LockBrush}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="22,4"/>
</Trigger>
</Style.Triggers>
</Style>
I can't seem to find a good way to apply this VisualBrush image AND a background color to the entire TextBox. I either get strange stretching issues or simply cannot fill the whole TextBox (controls stretch and are different widths depending on the rendering view).
Ideas?
Instead of a VisualBrush use a Control Template.
XAML
<Style x:Key="LockIcon"
TargetType="Path">
<Setter Property="Height"
Value="16" />
<Setter Property="Width"
Value="16" />
<Setter Property="Stretch"
Value="Uniform" />
<Setter Property="Data"
Value="F1 M 80.6667,55.1172L 80.6667,35.3333C 80.6667,15.851 64.815,3.05176e-005 45.3333,3.05176e-005C 25.8509,3.05176e-005 9.99998,15.851 9.99998,35.3333L 9.99998,55.1172L 0,56L 0,129.333L 45.3333,133.333L 90.6667,129.333L 90.6667,56L 80.6667,55.1172 Z M 20.6667,54.1771L 20.6667,35.3333C 20.6667,21.7318 31.7317,10.6667 45.3333,10.6667C 58.9349,10.6667 70,21.7318 70,35.3333L 70,54.1771L 45.3333,52L 20.6667,54.1771 Z " />
</Style>
<Style TargetType='TextBox'
x:Key='WithLockIcon'>
<Setter Property='MinHeight'
Value='26' />
<Setter Property="Padding"
Value="22,4" />
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<!-- Use a control template instead of
Background property -->
<!--<Setter Property="Background"
Value="{StaticResource LockBrush}" />-->
<!--<Setter Property="Padding"
Value="22,4" />-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<!-- Set background here!-->
<Border BorderThickness="4"
BorderBrush="Transparent"
HorizontalAlignment='Stretch'>
<StackPanel Background='#dddddd'
Orientation='Horizontal'>
<Path Style="{StaticResource LockIcon}"
Fill="Red" />
<ScrollViewer Margin="0"
x:Name="PART_ContentHost">
</ScrollViewer>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<TextBox x:Name='textbox1'
Text='Example Text'
IsEnabled='False'
Style='{StaticResource WithLockIcon}' />
<ToggleButton Checked='ToggleButton_Checked'
Unchecked='ToggleButton_Unchecked'
Content='Change State' />
</StackPanel>
I've achieved a reasonably close simulation in a similar situation.
<Window x:Class="VisualBrushMargins.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"
Background="{DynamicResource WindowBackground}">
<Window.Resources>
<VisualBrush x:Key="WindowBackground" Stretch="UniformToFill">
<VisualBrush.Visual>
<Grid>
<Border Background="DarkGreen" Width="250" Height="150" />
<Canvas Height="130" Width="180" Background="DarkBlue">
<Path>
<!-- path goes here -->
</Path>
<Ellipse Width="100" Height="100" Stroke="Red" />
</Canvas>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Window.Resources>
<Grid/>
</Window>
The path fits the canvas. Sizing the canvas and the border differently allows to add a "margin" to the brush -- note how it behaves on window resize. (Canvas is colored blue for illustrational purpose -- actually it's supposed to be transparent)
How to create a trigger, which if mouse hover that textblock, the text will change color.
just try this with background or foreground
<TextBlock Text="Hello" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextBlock.Background" Value="red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Window x:Class="WpfApplication1.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="TextBlockMouseOverStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TextBlock Background="Blue" Style="{StaticResource TextBlockMouseOverStyle}" Text="Foo" />
</Grid>
</Window>
I am beginner on WPF and need your help.
Problem:
I have 4 buttons on the form and need to apply 2 different style on pair of 2 buttons.
Is there any way we can achive this ?
please provide me sample if possible...
Thanks in advance...
You can define named styles and then assign them explicitly to any controls as you wish.
Here is a primer for styling buttons: Getting Started with WPF : Button Control Part 2 – Basic Styling
And here is an example:
<Window x:Class="WpfButtonStyling.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="250" Width="400">
<Window.Resources>
<Style x:Key="ButtonStyle1"
TargetType="{x:Type Button}">
<Setter Property="Foreground"
Value="Red" />
<Setter Property="Margin"
Value="10" />
</Style>
<Style x:Key="ButtonStyle2"
TargetType="{x:Type Button}">
<Setter Property="Foreground"
Value="Blue" />
<Setter Property="Margin"
Value="10" />
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button x:Name="FirstButton"
Content="First!"
Style="{StaticResource ButtonStyle1}"/>
<Button x:Name="SecondButton"
Content="Second"
Style="{StaticResource ButtonStyle2}" />
</StackPanel>
</Grid>
</Window>
If someone want to write Style directly in Button, write like below:
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="TimesNewRoman" />
<Setter Property="FontSize" Value="50"/>
<Setter Property="Background" Value="Green"/>
</Style>
</Button.Style>
</Button>
Use this Code For different styles for different buttons or any other
<Window x:Class="WpfApplication1.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"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<Window.Resources>
**<Style x:Key="a" TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="FontSize" Value="50"/>
<Setter Property="Background" Value="Indigo"/>
</Style>
<Style x:Key="b" TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="16"/>
</Style>
<Style x:Key="c" TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="TimesNewRoman" />
<Setter Property="FontSize" Value="50"/>
<Setter Property="Background" Value="Green"/>
</Style>
</Window.Resources>
<Grid>
<TextBlock Margin="26,41,39,0" Style="{StaticResource a}" Height="100" VerticalAlignment="Top">TextBlock with Style1</TextBlock>
<TextBlock Margin="26,77,39,0" Height="32" VerticalAlignment="Top">TextBlock with no Style</TextBlock>
<TextBlock Margin="26,105,67,96" Style="{StaticResource b}">TextBlock with Style2</TextBlock>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="26,170,-26,0">
<Button Style="{StaticResource c}">
<Bold >Styles</Bold></Button>
<Button Style="{StaticResource c}">are</Button>
<Button Style="{StaticResource c}">cool</Button>
</StackPanel>
</Grid>
here i declaring the style for both textBlock and button.Use this one..
I want to apply a style to all classes derived from Control. Is this possible with WPF?
The following example does not work. I want the Label, TextBox and Button to have a Margin of 4.
<Window x:Class="WeatherInfo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Wetterbericht" Height="300" Width="300">
<Window.Resources>
<Style TargetType="Control">
<Setter Property="Margin" Value="4"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel Margin="4" HorizontalAlignment="Left">
<Label>Zipcode</Label>
<TextBox Name="Zipcode"></TextBox>
<Button>get weather info</Button>
</StackPanel>
</Grid>
</Window>
Here's one solution:
<Window.Resources>
<Style TargetType="Control" x:Key="BaseStyle">
<Setter Property="Margin" Value="4"/>
</Style>
<Style BasedOn="{StaticResource BaseStyle}" TargetType="Button" />
<Style BasedOn="{StaticResource BaseStyle}" TargetType="Label" />
<Style BasedOn="{StaticResource BaseStyle}" TargetType="TextBox" />
</Window.Resources>
<Grid>
<StackPanel Margin="4" HorizontalAlignment="Left">
<Label>Zipcode</Label>
<TextBox Name="Zipcode"></TextBox>
<Button>get weather info</Button>
</StackPanel>
</Grid>
This is not possible in WPF. You have a couple of options to help you out:
Create one style based on another by using the BasedOn attribute.
Move the common information (margin, in this case) into a resource and reference that resource from each style you create.
Example of 1
<Style TargetType="Control">
<Setter Property="Margin" Value="4"/>
</Style>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type Control}}">
</Style>
Example of 2
<Thickness x:Key="MarginSize">4</Thickness>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="{StaticResource MarginSize}"/>
</Style>