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..
Related
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"
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>
In WPF is there container like an HTML div (where this is easy), where I could target all textblocks within that container? So I do not have to specify the style on every textblock?
I have a complex canvas and in just a region I would like to target the textblocks.
Something to the effect of this (where something other than StackPanel that would work as a style targeting container):
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="FontFamily" Value="Arial"></Setter>
</Style>
</StackPanel.Resources>
<TextBlock Canvas.Left="87" Canvas.Top="210">
mytext1
</TextBlock>
<TextBlock Canvas.Left="87" Canvas.Top="232">
mytext2
</TextBlock>
<TextBlock Canvas.Left="87" Canvas.Top="254">
mytext2
</TextBlock>
</StackPanel>
So if I try a grid the canvas coordinates get ignored and my textblock appears at the top of the canvas.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Canvas Width="500" Height="500">
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red"></Setter>
</Style>
</Grid.Resources>
<TextBlock Text="MyTextBlock1" Canvas.Left="300" Canvas.Top="300">
</TextBlock>
</Grid>
</Canvas>
In this case you are using the canvas coordinates to give 87 spacing on the left and 22 spacing between tops of elements. The StackPanel is already laying out the items one after another. You just need to set the margins for your textblocks
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="FontFamily" Value="Arial"></Setter>
<Setter Property="FontSize" Value="14" />
<Setter Property="Margin" Value="87,4, 0, 4" />
</Style>
</StackPanel.Resources>
<TextBlock>mytext1</TextBlock>
<TextBlock>mytext2</TextBlock>
<TextBlock>mytext3</TextBlock>
</StackPanel>
To answer your question you can use a Grid control (or Canvas or any other element) wherever you wish to isolate a Resources section. Grid does not perform any layout.
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="FontFamily" Value="Arial"></Setter>
</Style>
</StackPanel.Resources>
<TextBlock>
mytext1
</TextBlock>
<Canvas>
<Canvas.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="FontFamily" Value="Times"></Setter>
</Style>
</Canvas.Resources>
<TextBlock Canvas.Left="87" Canvas.Top="210">mytext2</TextBlock>
<TextBlock Canvas.Left="87" Canvas.Top="232">mytext2</TextBlock>
</Canvas>
</StackPanel>
VerticalScrollBarVisibility works when I define it inline like this:
<UserControl x:Class="TestScrollBar.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">
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="EditListContainerContentMultiLineTwoColumn">
<Setter Property="AcceptsReturn" Value="True"/>
<Setter Property="Width" Value="400"/>
<Setter Property="Height" Value="300"/>
<Setter Property="IsReadOnly" Value="False"/>
<Setter Property="Margin" Value="0 0 0 20"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" Margin="10">
<StackPanel HorizontalAlignment="Left">
<TextBox Text="this is a test"
Style="{StaticResource EditListContainerContentMultiLineTwoColumn}"
VerticalScrollBarVisibility="Auto"
/>
</StackPanel>
</Grid>
</UserControl>
But when I put VerticalScrollBarVisibility in a style, it shows me a blank screen:
<UserControl x:Class="TestScrollBar.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">
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="EditListContainerContentMultiLineTwoColumn">
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="AcceptsReturn" Value="True"/>
<Setter Property="Width" Value="400"/>
<Setter Property="Height" Value="300"/>
<Setter Property="IsReadOnly" Value="False"/>
<Setter Property="Margin" Value="0 0 0 20"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" Margin="10">
<StackPanel HorizontalAlignment="Left">
<TextBox Text="this is a test"
Style="{StaticResource EditListContainerContentMultiLineTwoColumn}"
/>
</StackPanel>
</Grid>
</UserControl>
In WPF it works works fine.
How can I get VerticalScrollBarVisibility to work in a style?
It is not working because these properties are not dependency ones and cannot be applied with style. Unfortunately using the attached property on the ScrollViewer is also not working, because they are not template bound in the default style.
The only thing I can think of you can do is to create an attached behavior that is setting the required values on the text box and apply it through the style.
I want to set the background property of all the usercontrols of my project.
I tried with
<style TargetType={x:Type UserControl}>
<setter property="Background" Value="Red" />
</style>
It compiles but didn't work.
¿Any Idea?
Thanks!
You can only set a a style to a specific class, so this will work (create a UserControl object, not very useful):
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<UserControl Name="control" Content="content"></UserControl>
</Grid>
But this doesn't (Create a class derived from UserControl):
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content"></l:MyUserControl>
</Grid>
What you can do is either explicitly set the style using the Style property:
<Window.Resources>
<Style TargetType="{x:Type UserControl}" x:Key="UCStyle">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content" Style="{StaticResource UCStyle}"></l:MyUserControl>
</Grid>
or create a style for each derived class, you can use BasedOn to avoid duplicating the style content:
<Window.Resources>
<Style TargetType="{x:Type UserControl}" x:Key="UCStyle">
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="{x:Type l:MyUserControl}" BasedOn="{StaticResource UCStyle}" />
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content"></l:MyUserControl>
</Grid>
I think you're missing some double quotes:
Try this:
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<UserControl Name="control" Content="content"></UserControl>
</Grid>