ThinkGeo.com    |     Documentation    |     Premium Support

Restyling the Zoom Tracker

A quick one folks:   Is it possible to restyle the Zoom tracker?  I want to change the border color and fill.   I've got some fussy customers.


TIA.



Guys, any comments on this query?



Hi Klaus,



Sorry for the delaying; there are many ways to do this, but I think this is the easiest way. Just replace the default ExtentOverlay to this new one.

public class CustomExtentInteractiveOverlay : ExtentInteractiveOverlay
{
    protected override InteractiveResult MouseDownCore(InteractionArguments interactionArguments)
    {
        InteractiveResult result = base.MouseDownCore(interactionArguments);
        if (OverlayCanvas.Children.Count != 0)
        {
            Rectangle rectangle = (Rectangle)OverlayCanvas.Children[0];
            // set your style here.
            rectangle.Fill = new SolidColorBrush(Colors.Red);
        }
        return result;
    }
}



Just let me know if you have more queries.



Thanks,

Howard



Super Howard, thanks.


One thing though.  If I recall, you proposed a custom SelectExtentInteractiveOverlay in another posting ( I cannot seem to find it) to allow one to drag over a bunch of features and highlight.  I am starting to think that all of these features should be added to your default ExtentOverlay.  What do you think?


 



Dear Klaus, 
  
 I think you are talking about this post  
 gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/39/aft/7932/afv/topic/Default.aspx 
  
 Thanks 
 Raquib

Hi Klaus, 
  
 That’s definitely a good suggestion, and I think users will like this function. But another thing is that we need to add a property on the default extent overlay to target the layer we want to select. If one product is added, we need to add it to the other products, that’s why we need carefully consider about. 
  
 I think it’s better to be on the code community so that more users will see this feature. How do you think? 
  
 Thanks for your suggestion and also thanks to Raquibur. 
 Howard

Howard,


Instead of a property that takes a single layer the user wants to select, I would say this property takes an IEnumerable<FeatureLayer> as a user may want to select all features on the map within a given extent.   So, yes, this could get a little complex if not properly thought through.   I did something similar for my WpfMap tip where I pass a collection of layes to be searched using the QueryTools for each layer.   Here I use a lot of LINQ.


So, yes, I see your reason for being cautious.  I brought this up because, I would have to be changing the default ExtentOverlay multiple times within a session depending on the kind of action a user is currently requesting.  If they want to measure, I have to use the RulerInteractiveExtentOverlay.  If they want to select, I will need to use the SelectOverlay....   This is fine as long as there is no side effect on map performance.


I also agree, that you should just leave it in the code community for now and allow us developers to customize as we see fit.



Hi Klaus, 
  
 It’s really cool that passing the features collection in the extent overlay. One thing is that to integrate everything in one interactive overlay is not quite good because the more functions it has the more complicated to maintain. I’m not sure if you notice the InteractiveOverlays collection? I really recommend to add custom interactive overlay to this collection instead replace the default extent interactive overlay. You can categorize your functions with this custom collection and leaving the default overlay as well.  
  
 Also, thanks for your suggestions and feel free to let me know if you have more queries. 
  
 Thanks, 
 Howard

Agreed, more functions means more complex to maintain.


Yes, I noticed the InteractiveOverlay collection.  If i add do this,


 




            if (!map.InteractiveOverlays.Contains("RuleOverlay"))
            {
                var rulerOverlay = new RulerTrackInteractiveOverlay();
                map.InteractiveOverlays.Add("RuleOverlay", rulerOverlay);
            }

I do not get the ruler working.  When I right click and drag a line across the map, all I see is a blue line being drawn without the distance measurement.


However, i repplace the default extent overlay like this


 



   
                map.ExtentOverlay = new RulerTrackInteractiveOverlay();
            

I see the brown ruler with distance measurement when right clicking and dragging across map.


I guess my question is how exactly does one use the InteractiveOverlay collection and how does the map process this collection?



Hi Klaus,



I'm glad to explain how the interactive overlay works. First of all, let's put everything on the table. We have interactive overlay collection, one ExtentInteractiveOverlay, one TrackInteractiveOverlay and one EditInteractiveOverlay. These are all interactive overlays which are using for interacting with map mouse events. Extent, Track and Edit interactive overlay are special for you can access them on the map's property. While interactive overlay collection is for adding custom interactive overlays. Now I'll explain the order to raise the events. Let's take mouse down event for example; we will collect all the interactive overlays in current map, first collect the overlays from the interactive overlay collection, then the track overlay, edit overlay and the extent overlay at last. Then we loop the collected interactive overlays collection and call the MouseDown method in the interactive overlay to see if this returned InteractiveResult needs process other overlays, if it’s DoNotProcessOtherOverlays, we’ll break the loop and don’t raise the method MouseDownEventCore method; or else we continue.



Hope it makes sense. The problem in your logic is that, you added the RulerOverlay to the collection but set the TrackMode on the TrackOverlay not the new interactive overlay in the collection, so I think the problem is here. 



I think your question is related to this post; 

gis.thinkgeo.com/Support/Dis...aspx#19191



So the click method can be changed like this using the interactive overlay collection:

MeasureTrackInteractiveOverlay rulerTrackInteractiveOverlay = new MeasureTrackInteractiveOverlay();
rulerTrackInteractiveOverlay.TrackMode = TrackMode.StraightLine;
rulerTrackInteractiveOverlay.TrackEnded += (o, a) => { rulerTrackInteractiveOverlay.TrackShapeLayer.InternalFeatures.Clear(); };
wpfMap1.InteractiveOverlays.Add(rulerTrackInteractiveOverlay);
wpfMap1.Refresh(rulerTrackInteractiveOverlay);



Please have a try and let me know how it works.



Thanks,

Howard

 



Very good explanation .  It all makes sense now, thanks.  Code works well too. 


One last question:  If I slightly modify the snippet you posted with this line


  rulerTrackInteractiveOverlay.Refresh()

instead of


wpfMap1.Refresh(rulerTrackInteractiveOverlay);

 


I get NullReferenceException upon button click.  Why so?


 



Hi Klaus, 
  
 That’s because calling map.Refresh(overlay) does not simply call overlay.Refresh(); actually, it does more than that. map.Refresh(overlay) adds current overlay to the logic tree so that you can see the overlay on the map; while overlay.Refresh() only refreshes the logic tree, but doesn’t add to the logic tree. That’s why the exception throws. I know it seems similar but it exists slim difference. 
  
 Just let me know if you have more queries. 
  
 Thanks, 
 Howard

Got it, thanks.



Klaus, 
  
 You are welcome; just feel free to let us know if you have more queries. 
  
 Thanks, 
 Howard