I would like to gray out the image only instead of the entire button. The reason being is that the image on the button is partly transparent, so when the entire button is grayed out it just looks odd.
In the below image you can see the entire button is grayed out instead of just the visible image
related... sorta: Disabling Button with custom Content in Silverlight?
You will need to override the ControlTemplate for your button. How to do that?
Create a new style
In that style define the ControlTemplate
ControlTemplate find the definition for the visual state named "Disabled"
Change that so that it changes the image only, without greying out the entire button.
These are the relevant parts of your controls template
<ControlTemplate TargetType="Button">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<!-- other states go here -->
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0"
Storyboard.TargetName="DisabledImage"
Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- rest of the template goes here -->
</ControlTemplate>
The DisabledImage you reference in the visual state manager then would need to cover the image displayed on an enabled button entirely, so that when disabled, only the greyed out image is visible to the user.
Related
In Expression Blend 4, I want to change the Foreground of a custom button on different states. I'm just able to change the Background and BorderBrush.
Just like this:
If the state is "Normal", the color of text "Button" is Black, while the state is "Pressed", the color of text "Button" is White.
On Brushes Panel under Properties Panel, there're 3 properties but no Foreground property:
Who can help me? I'm so perplexed.
Edit
I find ContentControl have a Foreground property, but ContentPresenter haven't. Wether I should use ContentControl instead of ContentPresenter?
So far, I have not find some way to change Foreground by Blend(I mean that not in code). In code, just like that:
<ResourceDictionary ...>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="Template">
...
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
...
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Blue"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
...
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter .../>
...
</ResourceDictionary>
I encountered an issue with a ControlTemplate for ToggleButton I created.
When the button is Checked, a ColorAnimation is triggered and the control's background changes color. However, if the user enters the MouseOver state, another animation is triggered that affects the button's background as well.
When the mouse is no longer in the MouseOver state, the control does not return to the color it should be while it is in the Checked state. I'm not sure why this does not persist when the MouseOver state is triggered.
The VisualStateManager portion of my ControlTemplate looks sorta like this:
<VisualStateManger.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"></VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Gold" Duration="0:0:0.3" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="PaleGoldenrod" Duration="0:0:0.3" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
My workaround for the issue I was having involved creating a Grid that enclosed the Border.
For the CommonStates I made animation changes to the Border.Background and for the CheckedStates I made animation changes to the Grid.Background.
It achieves the visual effect I was looking for.
I'm trying to create a templated/custom control in Silverlight.
The base control can be a System.Windows.Controls.Button. The button has the following visual states:
<vsm:VisualStateManager.VisualStateGroups>
<!--Define the states for the common states. The states in a
VisualStateGroup are mutually exclusive to each other.-->
<vsm:VisualStateGroup x:Name="CommonStates">
<!--Define the VisualStates in this VistualStateGroup.-->
<vsm:VisualState x:Name="Normal"/>
<vsm:VisualState x:Name="MouseOver" />
<vsm:VisualState x:Name="Pressed" />
<vsm:VisualState x:Name="Disabled" />
</vsm:VisualStateGroup>
<!--Define the states for the focus states. The states in a
VisualStateGroup are mutually exclusive to each other.-->
<vsm:VisualStateGroup x:Name="FocusStates">
<!--Define the VisualStates in this VistualStateGroup.-->
<vsm:VisualState x:Name="Focused" />
<vsm:VisualState x:Name="Unfocused" />
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
My custom control requires another state, MouseButtonUp (MouseButtonDown can be represented by the predefined Pressed state). Here, the MouseButtonUp state will be interpreted as a MouseOver state by default, but I want the MouseButtonUp state
behaves differently from a MouseOver state.
How can I add this MouseButtonUp visual state? (MouseButtonUp states only exists after the user releases the mouse and before the user starts moving.
BTW: Should I use Custom Control or User Control? I've been very confused about these two. It seems both of them would work in lots of cases.
Thanks a lot.
UPDATE: Once we added this MouseButtonUp state, I could do the visual transitions like:
<vsm:VisualTransition From="Pressed" To="MouseButtonUp" GeneratedDuration="0:0:5" />
Or:
<vsm:VisualTransition From="MouseButtonUp" To="MouseOver" GeneratedDuration="0:0:5" />
The below line creates a Visual-State for you in your xaml.
<vsm:VisualState x:Name="MouseButtonUp">
...Your code for animation
</vsm:VisualState>
That's not all. It is useless unless you force your execution control to go to this Visual-State. Well, how do you do that? Here's how.
VisualStateManager.GoToState(this, "MouseButtonUp", true);
The above code will execute any animation that you might have defined in your 'MouseButtonUp' VisualState definition in your xaml. Call the above code statement wherever you feel your mouse had a MousebuttonUp state.
I'd like to know if is it possible to apply a Visual State (in WPF 4) to nested controls. I've got a stack panel that contains some elements I'd like to change according to variation state.
<StackPanel x:Name="panPremioRaggiunto">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="StatiComuni">
<VisualState Name="PremioNonRaggiunto" />
<VisualState Name="PremioRaggiunto">
<Storyboard>
<ColorAnimation Storyboard.TargetName="lblPremioRaggiunto" Storyboard.TargetProperty="Foreground" To="Green" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock x:Name="lblPremioRaggiunto">TEXT</TextBlock>
</StackPanel>
When I try to change the state of entire stack panel with this code
VisualStateManager.GoToState(panPremioRaggiunto, "PremioRaggiunto", False)
nothing happens: nested textblock named lblPremioRaggiunto don't change his color according. Can I apply a visual state in this manner?
Thanks,
Danilo.
Yes, VisualStateManager can change the state of any control. You must have some other issue with your code.
Fixed issue: visual states are defined outside a control template so I have to use VisualStateManager.GoToElementState instead of GoToState.
My question is simply: is it even possible?
Suppose I want to style a ListBoxItem such that it has a black foreground by default, blue when selected, and red when the mouse is over it. I ended up with something like this:
<!-- assume the default foreground color is black -->
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0:0:0.2" To="Red" Storyboard.TargetName="contentControl" Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Duration="0:0:0.2" To="Blue" Storyboard.TargetName="contentControl" Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="contentControl" Foreground="{TemplateBinding Foreground}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
The problem is that the ListBoxItem class has correctly placed selection states in their own visual state group, separate to common states such as mouse over. That means that a ListBoxItem can be in both the selected and mouse over state.
If the ListBoxItem is selected and correctly displayed in blue, mousing over it will revert it to black because it transitions back to the normal state.
Is there any way for me to handle this without resorting to subclassing ListBoxItem and adding my own custom states? Everything I've read suggests that it is not possible, but it seems ridiculously limiting to me. What am I missing?
You basically asking for Foreground to be black AND blue at the same time. Now that is just impossible. This conflict could be resolved if individual states had precedence, like MouseOver > Selected > Normal > Unselected. But it would introduce unnecessary complication to already complicated visual state manager. Typically this situation is resolved by adding new element and animating that element's properties in one of the conflicting state groups.
Custom styled listbox - how can I keep the style for a selected item?