Using Raster Images in Silverlight for buttons - silverlight

I have buttons supplied to me from photoshop for different button states.
It looks like this
<Button x:Name="ResultsBtn" Click="ResultsBtn_Click" FontSize="27" BorderThickness="0" Padding="-10" Margin="-10">
<Grid>
<Image Source="..But_01_Idle.png" Width="496"/>
<TextBlock Text="Results" Margin="174,21,172,23" Width="90" Height="40" Foreground="White" />
</Grid>
</Button>
The button looks right for just one state.
I want to use expression blend to record a state and change the background behind an image (in this instance an outer glow) or change the source on a state change.
I've noticed that blend only seems to record position and transforms and not changes in attributes.
Should I be doing this in code or rather have the photoshop file sent in a particular format so that it can be automatically converted by blend

Okay, I'm actually quite surprised at Blend: it does not seem to allow you to animate the source property. However, Silverlight allows it so I assume WP7 will also allow it; this looks like a bug in Blend 4. However, I still would not recommend it using an image based approach because the images will deform and look bad/pixelated when significantly scaled up or down. A better approach is to edit your button's control template and modify it to match your reference artwork. You can even using File -> Import Adobe Photoshop File ... to pull the basic artwork into Blend. Then it's just a matter of shuffling it into the control template.
If you're dead set on using images (which will increase the size of your XAP and actually cause slower load UserControl load times), you can go about it as follows in Blend:
Create a new project and add a Button to your root visual element.
Create a new project folder called Images and add two images to it. (I used Koala.jpg and Penguins.jpg from the Sample Pictures folder.)
Right click the button and select Edit Template -> Edit a Copy...
The default template will contain a Grid that contains a Border named Background. Inside the Background border is a Grid that contains a Rectangle and another Border. Delete both of those innermost elements.
Now add an Image as a child of the Background border's Grid.
Now switch to the XAML editor and modify your control template's visual state groups to match the following code. (Look for the two "Added" comment blocks.)
Run the project. On mouse over you'll see penguins. Click and hold the left mouse and you'll see a koala.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<!-- Added -->
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TheImage" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="/Images/Penguins.jpg"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<!-- End of Added -->
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="#FF6DBDD1" Storyboard.TargetProperty="(Border.Background).**(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>
<!-- Added -->
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TheImage" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="/Images/Koala.jpg"/>
</ObjectAnimationUsingKeyFrames>**
<!-- End of Added -->
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="White" CornerRadius="3">
<Grid Background="{TemplateBinding Background}" Margin="1">
<Image x:Name="TheImage" Source=""/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" RadiusY="3" RadiusX="3"/>
<Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#FF6DBDD1" StrokeThickness="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

Visual States are built with animations, so you can only change things that can be animated (and expect typical results). I've never tried it, but my instinct tells me an Image source cannot be animated so the VSM is probably not a viable way to manage that.
Opacity, however, can be animated, so you could have both Image's in ytour button and control their Opacity with States. Just a thought.

You have to create a ControlTemplate:
Code for Button:
<Button Template={DynamicResource ButtonTemplate}/>
In your Resource Dictionary:
<ControlTemplate x:Key="ButtonTemplate" {x:Type Button}>
<Grid Padding="-10" Margin="-10">
<Image x:Name="IdleState" Source="..But_01_Idle.png" Width="496"/>
<Image x:Name="MouseOverState" Source="..But_01_MouseOver.png" Width="496"/>
<Image x:Name="PressedState..." etc/>
<TextBlock Text="Results" Margin="174,21,172,23" Width="90" Height="40" Foreground="White" FontSize="27"/>
</Grid>
</ControlTemplate>
Then, in Blend, Edit the Template and you'll find the States as Mike said. Use the Properties panel to hide / show your images for each state you want to style and you should be done.

Related

Can I change the VisualState of a DataTemplate in a ItemTemplate?

I have some controls in a DataTemplate and I'd like to control it's pressed state behaviour. I did the following where I just put in VisualStateManager in the DataTemplate but it doesn't seem to work. I think it's possible to understand what I'm trying to do below. Is it possible to do it inline inside the DataTemplate tags?
<ItemsControl ItemsSource="{Binding Items}">
....
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid ...>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
...
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="GridItemBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" ...>
...
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The short answer is that there is no "Pressed" visual state for the control type you're targeting -- so while you can reference any state in the Visual State Manager, it won't matter, because the control's code will never put it into that state.
You can see which visual states a control supports by looking at its definition (they're declared using the TemplateVisualState attribute), or by looking at this section on MSDN.
The way to go here might be to use the Button (or an override of [ButtonBase][2] that you write), since that has the "Pressed" visual state built in. You'd just have to write a Control Template for it that provides the layouts/styles that you're after.
Edit Here's an example:
Control template (resources section). This is a control template for the Button control, but it's not really a button. I'm just using it to take advantage of the "Pressed" visual state functionality.
<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="GridItemBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="GridItemBorder" BorderBrush="Orange" BorderThickness="1" Background="White">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
Items control
Define the item template as a "Button" which uses the above ControlTemplate.
<ItemsControl ItemsSource="{Binding SelectedItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Template="{StaticResource MyButtonTemplate}" Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Applying visual state to Border element

I am learning how to work with VisualStates, and have this problem:
I have a Control template which has Grid inside, and grid contains image and two TextBlocks. I would like to place a rectangle whenever a mouse if over a control. Most of the examples on internet use Blend, which I currently don't have, and also I would like to learn to do this manually. Here is a simple template (I have used constant colors to make it simpler):
<ControlTemplate x:Key="MyControlTemplate" TargetType="SomeControl">
<Grid Cursor="Hand" Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="None" Source="{Binding ImageUrl}" />
<TextBlock x:Name="TitleElement" Grid.Column="1" Margin="4" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Content}" Foreground="{StaticRecource TitleForegroundBrush}" />
<TextBlock x:Name="DescriptionElement" Grid.Row="1" Grid.Column="1" Margin="4,0,4,4" MaxWidth="200" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Description}" Foreground="{StaticResource DescriptionElementForeground}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource TitleElementFocusedForeground}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
Changing the TitleElement's Foreground on mouse over is working. Now I would like to have a border over whole control on mouse over (not just part of it). First thing I tried is placing a Border as a container of grid and putting a StoryBoard inside VisualStateGroup:
<Border x:Name="ControlBorder" BorderBrush="{StaticResource ControlBorderBrush}" BorderThickness="0">
<Grid Cursor="Hand" Width="Auto">
....
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource TitleElementFocusedForeground}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlBorder" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="1" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
This didn't work, as a matter of fact, now TitleElement doesn't even change foreground color, as it used to. However, adding a Border as 4th element inside a grid (RowSpan and ColumnSpan set to whole grid) works!, but there are some side affects which I don't like, for example, rectangle is "blinking" when I am moving mouse over control. Questions:
Why putting Grid inside Rectangle doesn't work, but putting Rectangle inside grid works?
I see that there is a CommonStates VisualGroup, which must be predefined somewhere. How do we know which ones are predefined, and their respective names?
What is the scope of VisualStateManager? If I define it inside an element, does it belong just to that element, or whole ControlTemplate?
Thanks.
Visual states need to be managed on the root element of the control template, if you put an element around your root they will be ignored, you will need to move them up.
On the styles and templates page of the controls the specific states are listed, common states should be the same for all (as they are "common"), the ones which are supported are also listed on the pages for the controls. (e.g. Button has Normal, Pressed, MouseOver and Disabled)
Applies to the whole template (see 1.)

Show Password Char by Customizing Style for PasswordBox in Silverlight for Windows Phone 7

I want to create my own password box in order to handle background state when password box is focus or lost focus. This is the style for my password box:
<Style x:Key="GamePasswordBox" TargetType="PasswordBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="PasswordBox">
<Grid>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates">
<vsm:VisualState x:Name="GotFocus">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To=".6"/>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="LostFocus">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Border x:Name="Background" CornerRadius="0" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
<Grid Background="{TemplateBinding Background}" Margin="0">
</Grid>
</Border>
<ContentPresenter
x:Name="contentPresenter"
Content="{TemplateBinding Password}"
Margin="{TemplateBinding Padding}"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is the password box now shows the input chars instead of mask password chars. How to fix this problem?
Looking at what gets generated by Expression Blend when templating a PasswordBox, it actually embeds another PasswordBox instead of having a ContentPresenter.
If you really need to use a ContentPresenter you may look at creating a value converter that takes the length of the string coming in and returns a string consisting of all PasswordChar with a length equal to the length of the input string.
Another option I've seen but I can't seem to find the original post right now is to use a font where every character looks like the password dot.
Edit: I found a font that is all password "bullets" you can get at http://hypv0141.appliedi.net/justbullets.ttf there may be better ones out there.

In XAML, What is the correct XML namespace for VisualStateManager?

I'm trying to restyle a few ToggleButtons. Apparently I cannot simply set the background to a new color, because there is a "Control Template" that provides the ToggleButton's visual behavior.
So what I need to do is specify in XAML a replacement "ControlTemplate" for the ToggleButton that provides different visual behavior, beyond the simple background color.
Q1. Is this correct?
I figured to start with the "default" controltemplate for the ToggleButton, which I grabbed from here, and then modify it. Actually that is the default ControlTemplate for Silverlight, I guess, and I am not using Silverlight, I'm using WPF. But... The corresponding doc page for WPF does not include a specification of the default controltemplate. It provides "a" ControlTemplate, which is not what I want.
Q2. I'm not sure if it matters that I am using the thing from Silverlight. Does it?
In the Silverlight example, there is an XML namespace prefix of of vsm applied to the VisualStateManager. Apparently the xml namespace is
xmlns:vsm = "clr-namespace:System.Windows;assembly=System.Windows"
... but somewhere else I read that this XML namespace "is no longer necessary."
This is all very very confusing.
In the Googlespace, there are references to something called "The WPF toolkit" which I have had prior exposure to - I used it for an autocomplete textbox prior to the release of WPF V4. I am guessing that some of the WPF Toolkit stuff was rolled into WPF for .NET v4.0, and that is why I no longer have to specify the WPF toolkit.
Q3. If someone could confirm that understanding I'd appreciate it.
Ok, now starting with the "default" ControlTemplate for ToggleButton, my first step was to compile it, before making any changes. It does not compile, failing with
c:\dev...\ToggleButtonStyle1.xaml(23,14): error MC3074: The tag 'VisualStateManager.VisualStateGroups' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'. Line 23 Position 14.
Clear enough. I then
looked at the documentation for specifying VisualStateManager in XAML. It, confusingly enough, specifies two xml namespaces, one of them is the one I actually used.
Q4 Um, which of these am I supposed to use? One of them, I DID use, and it didn't work. The documentation is completely unclear on what it means to specify TWO XML namespaces. (off with their heads!)
I have a reference to PresentationFramework.dll in the project file:
<ItemGroup>
....
<Reference Include="PresentationFramework" />
</ItemGroup>
I am not using Visual Studio here; I'm using a text editor. I want to understand how it works, not what buttons to push.
Thanks for any help y'all can provide.
Just a side comment - this all seems very very complicated. All I want to do is change the color of a ToggleButton when it is ON. It really shouldn't be this complicated.
You don't need to specify a namespace for the VSM (the http://schemas.microsoft.com/winfx/2006/xaml/presentation namespace is the default WPF namespace, declared as xmlns="..." in most standard .xaml's) -- you can however only use it at certain parts of your visual hierarchy.
For example, when I use the VSM in a standard UserControl, it looks something like so:
<UserControl x:Class="Whatever"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<!-- Storyboards go here -->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>
Placing the VSM xaml at this level will enable your storyboards to refer to any elements contained within the Grid. This works the same in a ControlTemplate like you're working with. One thing to note though, is that while in your own UserControls you can name the visual states whatever you like (because you'll ultimately be making calls to switch to that visual state in code), with the built-in controls, your visual states have to be named exactly what the control is expecting.
Answering my own question....
Q1 YES
Q2 No - it doesn't matter. The templates are "about" the same.
Q3 Not sure
Q4 I don't know.
The key here was that I needed to specify TargetFramework = 4.0. I had been compiling against v3.5, and the VSM I guess was first available in v4.0, so that was the reason for the "not found in namespace xxxxx" error.
I did not need to specify an XMLNS in the XAML file.
Stepping back - the answer to the larger question - how to get a ToggleButton that changes color when depressed... I tried fiddling with the builtin ControlTemplate, but it was too complicated for me to understand. The animations that occurred with the Press and Checked and so on - I could never figure out how to get it to just do what I wanted.
I stripped down the template into something much more spares, without all the gradients and animations, then I added back in a few animations and triggers to make it do about what I wanted it to do.
The visual effect is like this. ON:
OFF:
The XAML I used:
<ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key = "ToggleButtonStyle3"
TargetType = "ToggleButton">
<!-- This is a style (template?) for a toggle button. I wanted it to
change to a contrasty color when depressed. This took me a
loooooong time and much trial and error to figure out. The visual
effect is somewhat like the buttons in the compile output log in
Visual Studio, in which you can toggle the display of errors and
warnings.
-->
<Setter Property="Background" Value="#FFF7F0D2"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC4BC64" Offset="0"/>
<GradientStop Color="#FFADA658" Offset="0.375"/>
<GradientStop Color="#FFA19A52" Offset="0.375"/>
<GradientStop Color="#FF847E43" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid x:Name="ButtonGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="InnerRectangle" Storyboard.TargetProperty="Opacity" To="0.3"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="00:00:00"
Storyboard.TargetName="InnerRectangle"
Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
To="#FFF5BF0F"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To=".55"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation Duration="00:00:00"
Storyboard.TargetName="InnerRectangle"
Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
To="#FFF5D018"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name ="ButtonBorder"
CornerRadius ="1"
Background ="{TemplateBinding Background}"
BorderThickness ="{TemplateBinding BorderThickness}"
BorderBrush ="{TemplateBinding BorderBrush}">
<Border x:Name="InnerButtonBorder"
CornerRadius="1"
BorderThickness="2"
Background="#FFFAEB16">
<Rectangle x:Name="InnerRectangle" Opacity="1" Fill="#F7F0D2" />
</Border>
</Border>
<ContentPresenter
x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
TextBlock.Foreground="{TemplateBinding Foreground}"
Margin="{TemplateBinding Padding}"/>
<Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
<Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FFD1C44D" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<!-- This setter hides the desired element when the ToggleButton's initial state is checked -->
<Setter TargetName="ButtonBorder" Property="Background" Value="#FFF5D018"/>
<Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#FF000000"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="False">
<Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#78999999"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I put that into a separate file, call it ToggleButtonStyle3.xaml. Then I use it like this:
<Window.Resources>
<ResourceDictionary>
<Style ....
</Style>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/ToggleButtonStyle3.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
....
<ToggleButton Name ="btnShowAlerts"
IsChecked ="{Binding Path=ShowAlerts, Mode=TwoWay}"
Style ="{StaticResource ToggleButtonStyle3}"
Content ="alerts"
FontSize ="9"
Padding ="8,2"
Margin ="0"
ClickMode ="Press"
/>
I don't know if that's the best way to do things. I know that it doesn't keep with the "theme" of the desktop. I know it's probably pretty basic. I just know that it took me a loooong time to figure out how to get a ToggleButton that changed color.

WPF fails to resize a controle

I've already scoured my XAML file for the word "Width" and it only appears with a number as a value at the root element, setting the width of the entire control. The word "height" only has a numerical value at the root element and two textboxes that aren't in the same Grid cell as the checkbox below.
Unfortunately, regardless of the values I set in the UserControl element for height and width, the following checkbox doesn't get bigger:
<Style x:Key="CheckBoxStyle1" TargetType="CheckBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid ToolTipService.ToolTip="">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="path" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="lightbulb" Source="BestLogin_Images/lightbulb.png" ToolTipService.ToolTip=""/>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="140,0,0,0" Content="" ToolTipService.ToolTip=""/>
<Path x:Name="path" Data="M41.75,5.5 L53.75,2.25 L58.5,0.75 L65.75,1.5 L73,3.75 L83.25,8.25 L88.5,13.25 L95.5,21 L102,33.75 L102.5,44.5 L97.5,59.25 L90.25,74.75 L86.5,82.5 L84.25,91.5 L83.75,96.5 L79.5,104.25 L79.75,108.75 L78.5,113.25 L80,114.5 L79.75,119.75 L79,126 L76.75,132 L74.5,134.5 L68.75,140.5 L65,142 L64.53125,143.125 L62.75,144.75 L61.4375,145.59375 L57.71875,145.90601 L55.15625,143.46875 L53.4375,142.40625 L50.625,141.46875 L47.15625,137.34375 L43.5,135 L40.375,129.84375 L39.5,128.53125 L40.4375,127.375 L41.25,126.09375 L41.15625,124.78125 L39.15625,123.65625 L39.343998,121.5625 L39.343998,116.15625 L39.406498,111.3125 L38.750252,104.90625 L35.583599,99.791664 L35.292271,91.125 L33.375278,80.75 L31.54195,77.583336 L26.791613,69.75 L21.332918,59.541668 L19.874918,56.25 L19.08325,37.708332 L19.37525,36.75 L21.750242,27.333334 L27.041893,18.416666 L31.79188,11.833333 L37.416862,7.0833335 L38.791859,6.5833335 z" HorizontalAlignment="Left" Margin="19.083,0.75,0,18.094" Stretch="Fill" Fill="#B2FFF500" Opacity="0" ToolTipService.ToolTip="Click me to light up your day."/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...snip...(Grid layout)
<CheckBox Content="CheckBox" Style="{StaticResource CheckBoxStyle1}" HorizontalAlignment="Left" VerticalAlignment="Stretch" Grid.Row="2" Name="CheckBox1" />
Sizes of elements in WPF are determined by more than just Width and Height. You also need to consider all of the Alignment settings: HorizontalAlignment, VerticalAlignment, and sometimes HorizontalContentAlignment, and VerticalContentAlignment, as well as the layout Panels being used to arrange your elements. Here you've left-aligned the CheckBox so it will never get a bigger Width than the minimum it needs. You haven't included the Grid XAML but I suspect that the Row for the CheckBox may be set to Height="Auto" but I can't tell for sure without seeing the rest of the layout.

Resources