VisualStateManager for GraphicsLayer

679
7
01-04-2012 06:59 AM
JasonKnisley
Occasional Contributor
I'm running into some difficulty with getting the desired effect from the VisualStateManager for a GraphicsLayer.  Basically, I want a Normal state and MouseOver state to transition for unselected graphics.  However, when a graphic is in the Selected state I want the Normal and MouseOver states for that specific graphic to be ignored.  Is this possible within the constraints of the VisualStateManager?  In the examples I've seen so far it seems that people implement storyboards for states within CommonStates or SelectionStations, but not both.
0 Kudos
7 Replies
JenniferNery
Esri Regular Contributor
Sure, you can define both. For example, you can modify SelectMarkerSymbol in this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SelectGraphics to include CommonStates (Normal and MouseOver). On MouseOver, the Symbol will turn red.

   <esri:MarkerSymbol x:Key="SelectMarkerSymbol" >
    <esri:MarkerSymbol.ControlTemplate>
     <ControlTemplate>
      <Ellipse x:Name="Element" Width="15" Height="15" Fill="Cyan" Stroke="Black" >
       <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="SelectionStates">
         <VisualState x:Name="Unselected" />
         <VisualState x:Name="Selected">
          <Storyboard>
           <ColorAnimation Storyboard.TargetName="Element" 
            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
            To="Yellow" Duration="00:00:0.25"/>
          </Storyboard>
         </VisualState>
        </VisualStateGroup>

        <VisualStateGroup x:Name="CommonStates">
         <VisualState x:Name="Normal" />
         <VisualState x:Name="MouseOver">
          <Storyboard>
           <ColorAnimation Storyboard.TargetName="Element" 
            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
            To="Red" Duration="00:00:0.25"/>
          </Storyboard>
         </VisualState>
        </VisualStateGroup>
       </VisualStateManager.VisualStateGroups>
      </Ellipse>
     </ControlTemplate>
    </esri:MarkerSymbol.ControlTemplate>
   </esri:MarkerSymbol>
0 Kudos
JasonKnisley
Occasional Contributor
Jennifer,
Thanks for your response.  That's actually very similar to the solution I tried to implement, but it still has the same problem.  In this example the markers appear blue in their normal/unselected state, red in the mouseover state, and yellow in the selected state.

The problem appears when you mouse over a selected graphic.  In then goes from yellow (selected) to red (mouseover).  This part is fine.  However, on mouse leave it goes to normal (blue) rather than back to selected (yellow).  Therefore, from a visual standpoint, selected graphics only appear selected as long as you don't mouse over them again.

I'm trying to find someway to do one following:  either disable normal and mouseover state transitions entirely if a graphic is in the selected state, or on mouseleave transition the graphic back to it's previous state (selected if it was selected and normal otherwise).  Right now on mouse leave it always goes back to normal.
0 Kudos
JenniferNery
Esri Regular Contributor
Oh I see. Yeah, you are right. The Selection state is not preserved when it goes back to Normal from MouseOver. This seem related thread: http://forums.silverlight.net/t/46749.aspx/1

You can use the following Symbol Template instead:
   <esri:MarkerSymbol x:Key="SelectMarkerSymbol" >
    <esri:MarkerSymbol.ControlTemplate>
     <ControlTemplate>
      <Grid>
       <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="SelectionStates">
         <VisualState x:Name="Unselected" />
         <VisualState x:Name="Selected">
          <Storyboard>
           <ColorAnimation Storyboard.TargetName="Element" 
            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
            To="Yellow" Duration="00:00:0.25"/>
          </Storyboard>
         </VisualState>
        </VisualStateGroup>
        <VisualStateGroup x:Name="CommonStates">
         <VisualState x:Name="Normal" />
         <VisualState x:Name="MouseOver">
          <Storyboard>
           <ColorAnimation Storyboard.TargetName="Element2" 
            Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
            To="Red" Duration="00:00:0.25"/>
          </Storyboard>
         </VisualState>
        </VisualStateGroup>
       </VisualStateManager.VisualStateGroups>
       <Ellipse x:Name="Element" Width="15" Height="15" Fill="Cyan" Stroke="Black" />
       <Ellipse x:Name="Element2" Width="15" Height="15" Fill="Transparent" Stroke="Black" />
      </Grid>
     </ControlTemplate>
    </esri:MarkerSymbol.ControlTemplate>
   </esri:MarkerSymbol>
0 Kudos
JasonKnisley
Occasional Contributor
Very good.  I knew the solution had to be simpler than I was making it.  Thank you much.
0 Kudos
JasonKnisley
Occasional Contributor
Actually... that solution works well for marker symbols, but unfortunately I am dealing with polygons and need to use a SimpleFillSymbol.  While I can add multiple paths to a grid in its ControlTemplate without throwing an error, the only path that is ever visible is the path named "Element".  Element2 is completely ignored.  Any other ideas for use with a SimpleFillSymbol?

Edit:
As a further note, in the ControlTemplate for a MarkerSymbol it seems that the name of the various elements does not matter at all.  "Element" and "Element2" could just as easily be named "Foo" and "Bar" and everything still works assuming that the names are correctly referred to in the storyboards.  In contrast, in the ControlTemplate for a FillSymbol it appears that there must be a Path specifically named "Element" for the ControlTemplate to be applied.
0 Kudos
dotMorten_esri
Esri Notable Contributor
MarkerSymbols does not have any template parts to them so yes you can name the elements what you want (or better yet not name them at all). Due to the nature of lines and polygons they require a specific templatepart.

wrt. to visual states, different groups must modify different properties. Two different groups shouldn't modify the same property as you are trying to do. This would create ambiguity between the states.
0 Kudos
JasonKnisley
Occasional Contributor
I had a feeling that would be the case.  I can accomplish my goal using events and symbols, but the Renderer/ControlTemplate approach would have been much cleaner had it been possible.  Thanks for the input.
0 Kudos