ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

VisualState vs Template

10 Feb 2016, 11:34

Hi,

I have a question about VisualStates. In the tutorials, the Template and Style system seems to be the way to go to provide multiple looks for a single Control. But that means that Control should have DependencyProperty related to Style parameters (like the ones that exist in the Control class). To me, it feels like you have to carry some styling information within the code-behind, while everything should be kept accessible by the designer only.

I've found out about the VisualState and how it basically works and I think that would be the proper way to define a Control style: everything stay accessible via the Xaml and therefore to the designer. Since I can't find it mentionned in the tutorial, I'm wondering if I'm actually right about that.

Let's say I have a Control that should basically expose one property to the code: IsSelected. That Control would have two different states, a default one and a highlighted one. I clearly see how to do that using templates but I'm not sure how that would work with VisualState.

From what I understand, I would define a VisualGroup that would contain two VisualState Unselected (by default) and Selected. I would then listen to a DependencyProperty in my Control, when IsSelected is set to true, I would call the VisualStateManager from the code to set the VisualState to Selected. These two VisualState would be defined within the ControlTemplate.

How does that sound? Do I understand correctly the purpose of VisualStates?
Thank you,
Alexandre.
Last edited by ZanAlex on 15 Mar 2016, 13:27, edited 1 time in total.
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: VisualState vs Template

11 Feb 2016, 17:22

A ControlTemplate is used to define the appearance of a Control, its visual tree. You can bind any of the properties defined by the Control to specify how it looks, or you can use the properties as Triggers conditions to change its appearance. The value of these properties determine the state of the Control:
UIElement.IsMouseOver = false -> Normal state
UIElement.IsMouseOver = true -> MouseOver state
Button.IsPressed = true -> Pressed state
Selector.IsSelected = true -> Selected state
VisualStates is an evolution of ControlTemplate.Triggers. It is focused on states and transitions between states, and provides a better way to define the animations on these transitions than using ControlTemplate.Triggers + Trigger.Enter/EndActions.

If you want to define your own states in your control, you just have to call GoToState(StateName) when the property (or group of properties) that affect that state are modified.

The example you exposed will look like this:
class SelectableControl: public Control
{
  ...
  public:
    static const DependencyProperty* IsSelectedProperty;
  protected:
    NsBool OnPropertyChanged(const DependencyPropertyChangedEventArgs& args)
    {
      if (args.prop == IsSelectedProperty)
      {
        NsBool isSelected = *static_cast<const NsBool*>(args.newValue);
        if (isSelected)
          GoToState(NSS(Selected));
        else
          GoToState(NSS(Unselected));
      }
      return ParentClass::OnPropertyChanged(args);
    }
};
<ControlTemplate TargetType="SelectableControl">
  <Grid>
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="SelectionStates">
        <VisualStateGroup.Transitions>
          <VisualTransition GeneratedDuration="0:0:0.1" To="Selected"/>
          <VisualTransition From="Selected" GeneratedDuration="0:0:0.3"/>
        </VisualStateGroup.Transitions>
        <VisualState x:Name="Unselected"/>
        <VisualState x:Name="Selected">
           <Storyboard>
             <ColorAnimationUsingKeyFrames
               Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
               Storyboard.TargetName="border">
               <EasingColorKeyFrame KeyTime="0" Value="Red"/>
             </ColorAnimationUsingKeyFrames>
           </Storyboard>
         </VisualState>
       </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Border x:Name="border" Background="Silver"/>
  </Grid>
</ControlTemplate>
 
ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

Re: VisualState vs Template

17 Feb 2016, 11:46

That's good, it's exactly what I've been looking for.

Is there a way to go to a VisualState using a Trigger? The code within OnPropertyChanged would be pretty much the same in most cases and being able to make that bridge in Xaml would be perfect.

EDIT:
I've just noticed I can't declare Symbols with the same name. Let's say I have a two Controls with Selected/Unselected states. Both are completely unrelated but I'd like to use the same name for these differente states. The problem does not rise in Blend, how could I do this with Noesis? Is there a way to declare all the Symbols in a same place for instance?
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: VisualState vs Template

26 Feb 2016, 13:04

Why you can't declare the same Symbol twice? Where and how are you declaring them?
Could you please paste here the error message you are receiving?
 
ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

Re: VisualState vs Template

26 Feb 2016, 17:37

I declare them out of my class like that:
#include "Blablabla.h"

NS_DECLARE_SYMBOL(Selected)
NS_DECLARE_SYMBOL(Unselected)

class MyClass
{
...
}
Here is the error I'm getting:
5>NanoWheelEntry.h(24): error C2086: 'Noesis::Core::Symbol `anonymous-namespace'::__sSymbolSelected': redefinition (compiling source file Export.cpp)
ItemTile.h(26): note: see declaration of '`anonymous-namespace'::__sSymbolSelected' (compiling source file Export.cpp)
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: VisualState vs Template

26 Feb 2016, 18:08

The NS_DECLARE_SYMBOL macro should be defined in the place where you are going to use the Symbol repeatedly (to avoid the Symbol creation from string that will be less efficient).

You should define the NS_DECLARE_SYMBOL in the .cpp file, and there is no problem to define the same symbol name in different .cpp files. Have you tried this?
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: VisualState vs Template

29 Feb 2016, 12:08

There are plans to stop exposing symbols in the public API by the way. It should be an internal thing.
 
ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

Re: VisualState vs Template

01 Mar 2016, 16:22

That should probably fix it indeed. I can't test that right now, but I will as soon as I can. Many thanks!
 
User avatar
jsantos
Site Admin
Posts: 2906
Joined: 20 Jan 2012, 17:18
Contact:

Re: VisualState vs Template

01 Mar 2016, 17:02

Ok, please confirm this whenever possible to mark the thread as solved.
 
ZanAlex
Topic Author
Posts: 66
Joined: 16 Jan 2015, 17:46

Re: VisualState vs Template

15 Mar 2016, 13:26

Worked fine, thank you for your help!

Who is online

Users browsing this forum: Google [Bot] and 3 guests