ThinkGeo.com    |     Documentation    |     Premium Support

WpfMap swallows mouse events

We are evaluating WpfMap for our application. One of the scenarios is to wrap the map on a sphere. See the following image:



We are using the well-known TrackballDecorator (from 3DTools) to allow the user to rotate the globe with the mouse cursor. The first problem we had was that the map would move when the user attempted to click and drag the globe. The user could click and drag the globe for a second (around a second), then WpfMap would take over the mouse and move (pan) the map.


I disabled panning like so: 


wpfMap.ExtentOverlay.PanMode = MapPanMode.Disabled;


which worked, BUT, even though the map never pans, it still swallows the mouse events after a second or so delay, as though the mouse-handling aspect of the panning mechanism is still there. Again, the user can only rotate the globe for a second or so until WpfMap decides to take over (or swallow) the mouse events.


Can you help? If we turn off panning, we would like to have all mouse events passed through the WpfMap control.


Thank you!


Best regards,

Thaine Norris

 



Thaine, 
  
   I am not sure why the event would be eaten however the quickest way to resolve this is to create a small sample application and send it to us.  How you send it depends on the size of the sample.  If you can fit the sample into a 500k zip then attach it to this forum post.  Please be sure the sample runs out of the box minus a reference to our components.  You wont need to send our dlls in the zip, which should save you a bunch of room, but please include the TrackBallDecorator dependencies.  If you can’t fit it into 500K then please open a ticket in our customer portal, you should have a few provided with your evaluation. 
  
 How to create a support ticket.  
 wiki.thinkgeo.com/wiki/Map_Suite_Support_Ticket_Guide#Creating_a_Support_Ticket 
  
 We are doing something similar internally but not with the WPF edition, we designed out own native component and use our WMS server. 
  
 David

Thaine, 
  
 One other quick thing to try would be to set the wpfMap.ExtentOverlay = null.  In this way it is removed from the InteractiveOverlay stack.  If setting it to null doesn’t work then you need to remove it from the map.InteractiveOverlay collection.  There are multiple interactive overlays by default and you will need to loop through them and find the ExtentInteractiveOverlay or something named like that.   
  
 The map.ExtentOverlay property is just a look up property into the map.InteractiveOverlay collection, it searches for an item in that collection with a certain name.  Are you familiar with how the interactive overlays work in Map Suite? 
  
 David

 Hi David,


Thanks for getting back to me. I tried setting the ExtentOverlay to null and that crashed gloriously. No, I am not familar with the overlay architecture yet.


I have attached a VisualStudio 2010 project that will demonstrate the problem. Once you build it, try commenting out line 30 of MainWindow.xaml.cs, where the map object is added to the texture grid. This will enable you to play with the plain sphere and see how you should be able to drag it freely. Click and hold the mouse down and move it around.


Then uncomment line 30 and see how it works with a simple WpfMap texture-mapped to the globe. You cannot continue to rotate the globe as the mouse events are apparently stolen about a second after you begin moving the sphere.


Thank you for looking into this!


Best regards,

Thaine Norris

 



WpfMapOnSphere.zip (330 KB)

Thaine, 
  
   I was able to get your sample running and track down the surface cause of the panning not working as expected.  It all stems from a timer that we have running to monitor double clicks in the system.  I am still digging but when I disable that timer it pans smoothly and continuously.  Currently you have no way to disable the timer however as I dig deeper I hope to find the root cause and get a fix in.   
  
 David

David,


Thank you for looking into it! I look forward to what you come up with.


Thaine



Thaine, 



We have reviewed the issue and determined this is not really a bug in our product as it was not intended to be used this way.  We have limited resources for the forums and bug fixes so we need to move this issue to a venue that has the ability to solve the problem.  My feeling is that even if we solve this one issue related to the timer that this will just open up additional issues as you start to dive deeper into using the 3D tool such as track shape drawing etc.  My fear is that will will consume allot of support resources on this when it is really outside the scope of the forums.  My suggestion is that if you are interested in this technology that we move the issue to our professional services team as they are staffed to solve these issues and can give you the resource and time you need to get it working.  I will talk to one of the professional services reps here and he will e-mail you shortly to let you know your options. 



PS: I do really want to get this working but we just don't have the resources on this team. 



David





Thaine, 
  
   After checking out your website and seeing what you guys are doing I think we may be able to help out.  It seems like you wont be using zooming or track shape drawing.  Let’s get a meeting together and discuss it. 
  
 David

Thaine, 
  
   I hope to have something for you tomorrow. 
  
 David

Hi David, 
  
 Any news on this? 
  
 Thank you! 
 Thaine

Hello Thaine, 
  
 Sorry for delay, we are preparing our 5.5 release for now, we will update this as soon as we finish the release. 
  
 Sorry for the inconvenience, thanks for your patience. 
  
 Regards, 
  
 Gary

Hi Gary,  
  
 Any news on this?  
  
 Thank you!  
 Thaine

Hello Thaine, 
  
 We have released 5.5 new version, have you tried this? 
  
 If you still meet this problem, please let us know. Also I will contact product team to get more details and I will post here. 
  
 Thanks for your patience. 
  
 Regards, 
  
 Gary

Thaine,



  We have the panning and click scenario working fine.  What we needed to do was to create a new event manager and hook into the events on the 3D tools decorator.  It's a bit complicated but the good news is that you just need to include a new class and add a few lines of new code to hookup the events and the click and pan work.  Attached is a modified version of the sample you sent us.




            // New code to make the mouse click & pan work
            MouseEventManager eventManager = new MouseEventManager(_trackballDecorator);
            eventManager.MouseClick += new EventHandler<MouseButtonEventArgs>(eventManager_MouseClick);
            m_wpfMap.IsHitTestVisible = false;
 




using System;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace WpfMapOnSphere
{
    [Serializable]
    internal class MouseEventManager
    {
        public event EventHandler<MouseButtonEventArgs> MouseClick;

        private static int systemClickInterval = 150;
        private object tempMouseDownSender;
        private int mouseDownCount;
        private int mouseUpCount;

        [NonSerialized]
        private UIElement element;

        [NonSerialized]
        private DispatcherTimer timerMouseDown;

        [Obfuscation(Exclude = true)]
        private MouseButtonEventArgs tempMouseDownEventArgs;

        public MouseEventManager(UIElement element)
        {
            this.element = element;
            this.element.MouseDown += new MouseButtonEventHandler(OnMouseButtonDown);
            this.element.MouseUp += new MouseButtonEventHandler(OnMouseButtonUp);            

            timerMouseDown = new DispatcherTimer();
            timerMouseDown.Interval = TimeSpan.FromMilliseconds(systemClickInterval);
            timerMouseDown.Tick += new EventHandler(TimerMouseDown_Tick);
        }

        protected void element_MouseMove(object sender, MouseEventArgs e)
        {
            RaiseSpecialMouseEvent(tempMouseDownSender, tempMouseDownEventArgs);
        }

        protected void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
        {
            mouseDownCount++;
            tempMouseDownSender = sender;
            tempMouseDownEventArgs = e;
            timerMouseDown.Start();
        }

        protected virtual void OnMouseButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (timerMouseDown.IsEnabled)
            {
                mouseUpCount++;
            }
            else
            {
                mouseUpCount = 0;
                mouseDownCount = 0;
            }
        }

        protected virtual void OnSingleClick(object sender, MouseButtonEventArgs e)
        {
            EventHandler<MouseButtonEventArgs> handler = MouseClick;
            if (handler != null) { handler(sender, e); }
        }

        private void RaiseSpecialMouseEvent(object sender, MouseButtonEventArgs args)
        {
            if (timerMouseDown.IsEnabled)
            {
                timerMouseDown.Stop();
                if (mouseDownCount == 1 && mouseUpCount == 1)
                {
                    OnSingleClick(sender, args);
                }

                mouseUpCount = 0;
                mouseDownCount = 0;
            }
        }

        private void TimerMouseDown_Tick(object sender, EventArgs e)
        {
            RaiseSpecialMouseEvent(tempMouseDownSender, tempMouseDownEventArgs);
        }
    }
}

 


David



001_WpfMapOnSphere.zip (310 KB)

David, 
  
 Thank you very much for this! I tried the sample and it works perfectly. I will now have to integrate this into our application. 
  
 Thaine

Thaine, 
  
   If we had not been so buy we would have had it sooner.  I hope in the future I can see a demo of your product, it sounds really cool! 
  
 David