:::: MENU ::::

Show a tooltip for tapped pushpin on Windows Phone

I’ve been working on a Windows Phone project which includes a lot of pushpins on Bing maps which carry information important to the user. Now, I wanted some form of interaction in the form of a tooltip – user can request more information about particular pushpin by tapping on it. Of course, the word tooltip might be misleading because it usually involves mouse pointer placed above a control for a short period of time before the tooltip gets shown. There is no such thing on Windows Phone like placing a mouse pointer over a control, but the effect can easily be accomplished on tap event. I’ll show you how to do it in this article.

Now, let’s assume that we have a model called PushpinModel which holds the Pushpin object and some information about it, such as Name, Description and Date when it was added to some imaginary database. This is how we could describe such a model:

Next we could create a ViewModel in which we’ll populate ObservableCollection with some PushpinModels:

You’ll notice that you’re missing some references when you try to build the app, so add the following to the project:

We’ll only have the Bing map in MainPage. But first, add the Silverlight for Windows Phone Toolkit to your project. I used NuGet for it. Reference it in the MainPage.xaml:

Define the map control:

In the code behind, in MainPage.xaml.cs, add the following code:

And the result we get is:

Show tooltip on pushpin tap even

In order to show the tooltip on pushpin tap event, we’ll used the ContextMenu available in Silverlight for Windows Phone Toolkit. Add it to pushpin like this:

To show the ContextMenu on Tap event, we’ll use the Pushpin_Tap event handler:

The MenuItemStyle should be defined in the App.xaml, and look (for example), like this:

The app now looks like this:

You could even apply style the whole contextmenu to make it look more like a tooltip window. The whole map would then be defined like:

And the styles in App.xaml would be:

The final result:

 

This really looks good to me. What do you think? Let me know in comments or on Twitter!

Share the knowledge

No Comments

  • Reply Håkan |

    Well performed technically. But you should read up on the style guidelines for metro design. The gradient and rounded corners are chrome that do not add or support the information. Design it more clear and simplistic. Start by reading this: http://ux.artu.tv/?p=179

    ANd don’t give up on coding :)

    • Reply igrali |

      I wanted to show the possibilities, but I agree that it could’ve been more simplistic.

      Thanks for your comment! :)

  • Reply Kris Vandermotten |

    Your Pushpin_Tap method is way to complex. This will do the job too:

    private void OpenContextMenu(object sender, EventArgs e)
    {
    ContextMenuService.GetContextMenu(sender as DependencyObject).IsOpen = true;
    }

  • Reply Kevin Kutlesa |

    I’ve a got a small issue with your code. When I use the MenuStyle for the contextmenu, I get a NullReferenceException when it loads. I have no problem with the MenuItemStyle, but i can’t use the other one without the exception being thrown. Any idea on what I’m doing wrong? hahaha

  • Reply Kevin Kutlesa |

    Using your code as-is, only change I made was remove the Style=”{StaticResource MenuStyle}” from the context menu so it wouldn’t throw the exception, when i add it again, i get the exception when the “tap” event completes, i.e, when the contextmenu should display.

    I should’ve mentioned that. It’s not that I get an exception on loading, it’s only when I tap on the pushpin.

    • Reply igrali |

      I must ask these questions, even though they may seem a long shot:

      1. Is the _ppmodel maybe null?
      2. Are you sure you instantiated the viewmodel, so it isn’t null?
      3. Is the FirstOrDefault giving you a null for the DataContext?

      After all, if you don’t find the error, I could upload the solution/project somewhere if you wanted because I tested it (and I’m also using a similar concept in my application), and it works like a charm.

  • Reply Kevin Kutlesa |

    I’d love it if you could upload the project somewhere, it would help me a lot. Thank you

  • Reply Kevin Kutlesa |

    I want to run something by you, maybe you can help me figure it out…if it’s not too much to ask of course.

    In both your app and mine, I’ve noticed that if you click on the pushpin while the map’s still loading, you get a nullreferenceexception. Do you know of any way to prevent that? From what I’ve researched, the error is tied to the contextmenu and its UpdateVisualStates method, something having to do with onApplyTemplate() not being executed at the moment so a few variables are null.

    The problem lies in not having access to those parameters so I can’t check is _outerPanel is null, for example.

    Do you know any way around this? What I’d like to happen is that unless everything’s “fine” the tooltip is either unresponsive or maybe get a toast saying “map view not loaded” or anything else…

    I’ve racked my brain looking for an answer as well as scouring through search engines and still have come up with, well, zilch. So now I look to the experts, such as you hahaha

    • Reply igrali |

      You seem to know too much to not have tried this, but I’ll still ask – have you tried putting the code inside the tap event handler in a try-catch block?

      That should catch the exception, and from there you can display a messagebox or whatever…

  • Reply Kevin Kutlesa |

    To be honest, I hadn’t tried it, and the moment I read your reply, I had a veritable Homer Simpson moment, and by that I mean, “D’OH!!!”.

    But after putting the try-catch in place and see the exception somehow skipping it, I realized what was happening. It’s my original concern coming back. If I use the context menu’s style, I get a nullreferenceexception when the menu launches. I’d left the style in place when I was looking for a solution and forgot to remove it.

    Now I understand why your project kept throwing me exceptions. I still haven’t found what’s wrong, but considering both your tried and tested project throws the same error as mine, we can safely assume the problem’s on my end. Just don’t know what it is.

    Looking through it now, it really is related to the contextmenu styling, if I add any property, such as border, background, margin, anything really, when it opens it throws a NullReferenceException. Need to do some research on this, ’cause it doesn’t make any sense.

  • Reply Kevin Kutlesa |

    No matter where I put the try/catch block for the contextmenu launch, if the nullreferenceexception is launched (like i explained, when you click on the pushpin when the view still hasn’t fully loaded) it’s not captured by the block and goes straight into the app’s unhandled exception event, making it sort of an uncapturable exception.

    I’ve used the try/catch in these 2 ways: having the entire IF inside the try, or having just the contextmenu.isopen inside the try (with the catch following the try as normal)

    if (contextMenu.Parent == null)
    {
    contextMenu.IsOpen = true;
    }

    Any idea on what can be done?

    • Reply igrali |

      A friend of mine had an issue with weird exceptions on pushpin tap.
      He fixed it by updating all the referenced toolkits.

      Do you have the latest toolkit version?

  • Reply Kevin Kutlesa |

    I think so, but I might need to double check…I think something related to this issue presents itself when you use Tap insteado Hold, and I’ve read the solution lies in adding a nice little IF to check for nulls in a class in the tooltip source code and recompiling. Since both issues lie in the visual state not being updated, doing that might solve the problem for me…

    I’ll have to see what works, updating or editing.

  • Reply Kevin Kutlesa |

    Using this example, on the MenuItem Style’s control template, add a hyperlinkbutton and set the URL using its NavigateUri property.

    Hope this helps,
    Kevin Kutlesa

  • Reply Kevin Kutlesa |

    No problem, glad I could help. With the amount of questions I’ve had, it’s high time I start giving back hahaha

  • Reply Kevin Kutlesa |

    I finally found the solution to my problem and wish to share it here.

    My problem was that when the view wasn’t set or changed, interacting with the pushpins threw an exception. After trying anything I could fin I decided to go back to basics and check the documentation, article by article, and decided to start with the map events. There I found my solution, the ViewChangeStart and ViewChangeEnd events, which are triggered when the map view changes.

    In the start event I disabled my mapitemscontrol, using its IsEnabled property, so the user couldn’t interact with it. In the end event I re-enabled them.

    Hope this helps anyone who’s ever been in the same position as I’ve been.

    And igrali, I want to thank you for all the help and patience, really appreciate it.

    • Reply igrali |

      Well, it seems from your solution that I haven’t been very helpful, but I’m glad you shared your solution with others who may have the same issue. :)

    • Reply dotnetomaniak |

      Hi,
      Is it possible to share this solution somehow? I still have the same problem.
      I think it is a bug in the toolkit 7.1

      Regards,
      Dawid

  • Reply Kevin Kutlesa |

    Actually I cheated a bit there, instead of using Tap or Hold events on the tooltip, i used the Click event, which works the same and really didn’t cause any error once I figured out the viewchange start & end event solution.

    Give it a try.

    The Only thing I had to remove, because it was raising an exception (NullReference) no matter what I did, was the context menu style (MenuStyle in igrali’s code). I haven’t yet figured out why it raised the exception…

  • Reply darkesthour |

    As Kevin described you need to extend the ViewChangeStart and ViewChangeEnd events with your own functions which disable/enable the map.

    Firstly, define the handlers:

    private void disableMapHandler(object sender, MapEventArgs e)
    {
    Map map = (Map)sender;
    map.IsEnabled = false;
    }

    private void enableMapHandler(object sender, MapEventArgs e)
    {
    Map map = (Map)sender;
    map.IsEnabled = true;
    }

    Secondly, attach them to your Control, for example, in the Page constructor (assuming you named your control MapControl):

    MapControl.ViewChangeStart += new EventHandler(disableMapHandler);
    MapControl.ViewChangeEnd += new EventHandler(enableMapHandler);

    Many thanks for the fix Kevin.

  • Reply rober99 |

    With your code I get Error:
    XamlParseException occured
    Failed to create a ‘System.Type’ from the text ‘sltkit:MenuItem’.

    Thats in App.g.i.cs.
    It’s something with TargetType in App.xaml.
    How to fix this?

  • Reply Junell |

    I am having the same prob as Kevin Kutlesa. I cannot understand where to put mapPins.ViewChangeStart += new EventHandler(disableMapHandler);
    mapPins.ViewChangeEnd += new EventHandler(enableMapHandler);

    can you further expalined. Thank you!

  • Reply Junell |

    I’m Running the downloaded pushpinsample1 form skydrive and i got the same NullReferenceExeption.

  • Reply trung nguyen hoang |

    Hi Igrali, I can’t run your demo. when i click to pushpin, it was stoped. i’m a newbie in wp programming. So i hope you can help me. Thank you so much!

    • Reply trung nguyen hoang |

      error is here
      No symbols are loaded for any call stack frame. The source code can not be displayed.

      Microsoft.Phone.Controls.Toolkit.dll!Microsoft.Phone.Controls.ContextMenu.UpdateVisualStates(bool useTransitions) + 0x4f bytes

  • Reply affilorama review |

    What’s up i am kavin, its my first occasion to commenting anywhere, when i read this article i thought i could also make comment due to this good piece of writing.

  • Reply cheap jerseys for nba |

    Pretty section of content. I just stumbled upon your website
    and in accession capital to assert that I get actually enjoyed
    account your blog posts. Any way I’ll be subscribing to your feeds and even I achievement you access consistently quickly.

  • Reply turmeric |

    Making sure that supplement provides herbal ingredients extends those benefits.
    Research studies on the health benefits of turmeric both on
    humans as well as animals are numerous. John’s Medical College, black pepper increases the bioavailability of turmeric by 2000%.

So, what do you think ?