Custom States when a radio button is using gradients instead of a graphic
Hi Dorian,
I have a set of Radio Buttons that I customized by creating gradients in the background instead of a graphic like a checkbox or a bullet. I'd like the gradient to represent that the button has been "checked". I'd like to set this up so the checked gradient has it's own Normal, MouseOver and Pressed States. But obviously when I move my mouse away from my custom color in the "checked" state, it automatically returns to the common states. I get that. I created a set of custom visual states that I'd like to use while the radio button is "checked." See attached. How can I set this up?
Thanks always for your help!
-Jeremy
I have a set of Radio Buttons that I customized by creating gradients in the background instead of a graphic like a checkbox or a bullet. I'd like the gradient to represent that the button has been "checked". I'd like to set this up so the checked gradient has it's own Normal, MouseOver and Pressed States. But obviously when I move my mouse away from my custom color in the "checked" state, it automatically returns to the common states. I get that. I created a set of custom visual states that I'd like to use while the radio button is "checked." See attached. How can I set this up?
Thanks always for your help!
-Jeremy
Re: Custom States when a radio button is using gradients instead of a graphic
Hey Jeremy! Great to hear from you again; let's go through this! 😊
I'll start with a bit of theory/explanation, and then I'll get to some suggestions:
1) ABOUT VISUAL STATES
1A) Visual States: Core Concepts
One important notion to be aware of, is a concept of exclusivity and non-exclusivity within Visual States:
Exclusivity:
Within a single Visual State Group, all States are exclusive: What this means is that I cannot for example have a 'MouseOver' and 'Pressed' Visual State simultaneously active within the "CommonStates" Visual State group.
Non-Exclusivity:
However, multiple Visual States can be active at once, if each one is part of a different VisualState Group; what this means for example is that I can have a 'Checked' VisualState (from the 'CheckStates' VisualState Group), and a 'MouseOver' VisualState (from the 'CommonStates' VisualState Group) active at once. This is possible because the 'Checked' and 'MouseOver' States are part of different Groups.
This ability can however result in having the same Property 'taken control over' by multiple Visual States at once. For example, if a single TextBlock's fill is defined as different colors both in the 'Checked' and the 'MouseOver' Visual States, their simultaneous activation can cause undesired visual results.
All of this to say, that if taking the Visual State approach, we need to always be really careful that we are not overwriting a same Element's same Property between multiple Visual States that can be active at once.
I mention all of this, because my suspicion is that these mechanics may be at the root of why you are getting some conflicts in what is displaying when interacting with the Element.
1B) Visual States: Activation Mechanics
The next thing to know about VisualStates, is that many Elements have Visual States that already have their functionality built-in. For example, if you design a state for the RadioButton's 'Checked' State, it will automatically display when the Element is set to 'Checked'.
This 'automatic functionality' however does not apply when creating custom Visual State Groups. Since these custom Visual States can serve any desired purpose, which specific event makes them display, is up to the user to define. This is often accomplished by creating custom Triggers which would invoke a 'GoToStateAction' Action (this makes a chosen VisualState display).
Now where your particular situation comes in, is that Triggers are able to have one Binding each.
So, this is an easy operation if you wanted a Visual State to display on a 'Checked' RadioButton...but more complicated if you wanted it to fire on a 'Checked' AND a 'MouseOver'.
You could absolutely set it up so that your custom Visual States are fired by single Triggers, combined with the default RadioButton's VisualStates are fired by their included functionality, but it can get a bit messy to have different parts of the design controlled in different areas.
2) RECOMENDATIONS:
So, with all of the above in mind, there are two potential paths I'd recommend:
2A) If you want to take advantage of the cross-interpolation and animation features of Visual States:
In this case, I would completely kill off your custom Visual State Group, and instead work across the two built-in 'CommonStates' and 'CheckStates' of the RadioButton, ensuring that there are no conflicts between Elements and their Properties across all of these Visual States.
2B) If you don't need animations across your states:
Another great option here is to use Setters. In your specific use-case, what I personally am really attracted to in this solution is that you are able to really customize the conditions of a state beyond the limits of the functionality offered by the built-in Visual States.
With Setters, you can create unlimited combinations of conditions, all in one place, including being able to trigger these as a result of things not even related to input/interaction states. Their drawback however, is that Setters change Properties in a 'single frame', and don't have the same 'Timeline' functionality that Visual States offer.
So, just replicating your architecture, it could look like this if controlled by Setters instead:
If you've not used Setters before: Just a couple notes:
- The RadioButton comes with a couple already included; you can either add onto these or delete them and start your own set from scratch.
- You need to select an Element to apply Setters to before adding a new Setter. In the context of a RadioButton Template, selecting the RadioButton's Root Element (line with the purple icon in the navigator) is going to give you the biggest hitbox for the Element.
- Once you add a Setter, or if you select a Setter; you'll notice a red outline around the Stage. This is just like in a Visual State, or a Storyboard, red means you're 'recording' any Property changes you make.
3) CONCLUSION
Let us know if either of these approaches does the trick for you, and if there's anything else!
Catch you around!
- Dorian
I'll start with a bit of theory/explanation, and then I'll get to some suggestions:
1) ABOUT VISUAL STATES
1A) Visual States: Core Concepts
One important notion to be aware of, is a concept of exclusivity and non-exclusivity within Visual States:
Exclusivity:
Within a single Visual State Group, all States are exclusive: What this means is that I cannot for example have a 'MouseOver' and 'Pressed' Visual State simultaneously active within the "CommonStates" Visual State group.
Non-Exclusivity:
However, multiple Visual States can be active at once, if each one is part of a different VisualState Group; what this means for example is that I can have a 'Checked' VisualState (from the 'CheckStates' VisualState Group), and a 'MouseOver' VisualState (from the 'CommonStates' VisualState Group) active at once. This is possible because the 'Checked' and 'MouseOver' States are part of different Groups.
This ability can however result in having the same Property 'taken control over' by multiple Visual States at once. For example, if a single TextBlock's fill is defined as different colors both in the 'Checked' and the 'MouseOver' Visual States, their simultaneous activation can cause undesired visual results.
All of this to say, that if taking the Visual State approach, we need to always be really careful that we are not overwriting a same Element's same Property between multiple Visual States that can be active at once.
I mention all of this, because my suspicion is that these mechanics may be at the root of why you are getting some conflicts in what is displaying when interacting with the Element.
1B) Visual States: Activation Mechanics
The next thing to know about VisualStates, is that many Elements have Visual States that already have their functionality built-in. For example, if you design a state for the RadioButton's 'Checked' State, it will automatically display when the Element is set to 'Checked'.
This 'automatic functionality' however does not apply when creating custom Visual State Groups. Since these custom Visual States can serve any desired purpose, which specific event makes them display, is up to the user to define. This is often accomplished by creating custom Triggers which would invoke a 'GoToStateAction' Action (this makes a chosen VisualState display).
Now where your particular situation comes in, is that Triggers are able to have one Binding each.
So, this is an easy operation if you wanted a Visual State to display on a 'Checked' RadioButton...but more complicated if you wanted it to fire on a 'Checked' AND a 'MouseOver'.
You could absolutely set it up so that your custom Visual States are fired by single Triggers, combined with the default RadioButton's VisualStates are fired by their included functionality, but it can get a bit messy to have different parts of the design controlled in different areas.
2) RECOMENDATIONS:
So, with all of the above in mind, there are two potential paths I'd recommend:
2A) If you want to take advantage of the cross-interpolation and animation features of Visual States:
In this case, I would completely kill off your custom Visual State Group, and instead work across the two built-in 'CommonStates' and 'CheckStates' of the RadioButton, ensuring that there are no conflicts between Elements and their Properties across all of these Visual States.
2B) If you don't need animations across your states:
Another great option here is to use Setters. In your specific use-case, what I personally am really attracted to in this solution is that you are able to really customize the conditions of a state beyond the limits of the functionality offered by the built-in Visual States.
With Setters, you can create unlimited combinations of conditions, all in one place, including being able to trigger these as a result of things not even related to input/interaction states. Their drawback however, is that Setters change Properties in a 'single frame', and don't have the same 'Timeline' functionality that Visual States offer.
So, just replicating your architecture, it could look like this if controlled by Setters instead:
If you've not used Setters before: Just a couple notes:
- The RadioButton comes with a couple already included; you can either add onto these or delete them and start your own set from scratch.
- You need to select an Element to apply Setters to before adding a new Setter. In the context of a RadioButton Template, selecting the RadioButton's Root Element (line with the purple icon in the navigator) is going to give you the biggest hitbox for the Element.
- Once you add a Setter, or if you select a Setter; you'll notice a red outline around the Stage. This is just like in a Visual State, or a Storyboard, red means you're 'recording' any Property changes you make.
3) CONCLUSION
Let us know if either of these approaches does the trick for you, and if there's anything else!
Catch you around!
- Dorian
Re: Custom States when a radio button is using gradients instead of a graphic
I've been tinkering with Setters off and on over the past few weeks in between tasks. Finally figured out that you were talking about. Thanks again for your help Dorian!
Re: Custom States when a radio button is using gradients instead of a graphic
Right on, Jeremy🤘! Thanks for dropping by and sharing your results! Thrilled this all worked!
- Dorian
- Dorian
Who is online
Users browsing this forum: No registered users and 8 guests