WPF Design Mode quick tip

Hah! Found a little workaround for something that has been bugging me for quite some time.

Sometimes the design mode in Visual Studio or Expression Blend will fail to show a preview of your controls/windows/pages/etc, throwing a NullReferenceException. This happens because in addition to parsing the XAML file, design mode apparently also checks your codebehind, and since some stuff might not be running in design mode, some attributes might not be available. You can workaround this behaviour by checking the following method (and, for example, returning out of whichever method is crashing the design mode):

DesignerProperties.GetIsInDesignMode(...)

This wouldn’t have happened if I were correctly using MVVM, but oh well..

Google Maps WPF Control

Hi there!

In my current project I had to integrate a Google Map into my WPF application. This isn’t the most straightforward thing since Google pretty much only offers two alternatives: either use their Javascript API on a Web Application, or use their Web Services for geocoding/reverse-geocoding, etc. (they can also return static images, but I needed an actual map that I could interact with within my application).

I ended up developing a WPF Control for the Google Map. This control is quite simple, as it is only composed of a Web Browser and an html file (for the moment at least). This method can easily integrate any Javascrit API with a .Net application, so I’m going to post a little tutorial on how to do so.

Step 1: HTML File

First thing to do is the html file. You can check out the Google Maps Javascript API Tutorial for more info (and check their Reference as well), I’ll just write the necessary stuff here.

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
...
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

In our html file we’ll have to reference the Javascript API, so we set the // <![CDATA[
tags as above. The tag is there to make the control take up the whole viewport, and make it not user scalable.

Now we have to add the javascript code to load the map:

<script type="text/javascript">
        var map;
        var latlng;
        var lat;
        var lng;
        var zoom;

        function Init() {
            lat = 40.632915;
            lng = -8.68929;
            zoom = 18
            latlng = new google.maps.LatLng(lat, lng);
            var options = {
                zoom: 18,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.SATELLITE
            };

            map = new google.maps.Map(document.getElementById("map_canvas"), options);
        }
</script>
<body onload="Init()">
    <div id="map_canvas" style="width: 100%; height: 100%">
    </div>
</body>

If you open the html file, it should now show a Google Map, centered on the coordinates of your choosing.

Now, on any WPF application you could just load a WebBrowser control with this file, and it would work, but I needed different methods of interaction … So a bit more javascript and…:

        function Pan(x, y) {
            try {
                lat = lat + x;
                lng = lng + y;

                map.panTo(new google.maps.LatLng(lat, lng));
            }
            catch (ex) {
                window.alert("Pan:Error");
            }
        }

…We’ve got ourselves a Panning function. This is what I want to access from my WPF app.

Step 2: WPF Control

OK, now how to interact with the map from within the application. First thing: create a new control :)
The only thing this control has is a WebBrowser.

<UserControl x:Class="My.Controls.GoogleMapsControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
    <Grid>
        <WebBrowser Name="mapBrowser" Margin="25" />
    </Grid>
</UserControl>

The code-behind for the GoogleMapsControl, has the browser navigate to the html file we created, and then invokes the javascript code through methods, like so:

using System;
using System.Windows.Controls;

namespace My.Controls
{
    public partial class GoogleMapsControl : UserControl
    {
        public GoogleMapsControl()
        {
            InitializeComponent();

            mapBrowser.Navigate(new Uri("file://127.0.0.1/c$/Path/to/file/map.html"));
        }

        public void Pan(double x, double y)
        {
            this.mapBrowser.InvokeScript("Pan", x, y);
        }
    }
}

Since the Web Browser will be executing javascript code, your browser may show a little warning asking permission to execute said code. Running the file through “file://127.0.0.1/c$/…” shouldn’t show the warning.

And that’s it, a quick and easy Google Maps control. This should work with any other Javascript API (Bing maps, for instance..). WinForms also includes a web browser control, so this will also work there (although invoking a script is done using WebBrowser.Document.InvokeScript() ).

Maybe I’ll publish the control soon, there are still a few more features to implement, but thats the gist of it! ;)

See ya next time.

Hello World

Hello fellow people of the internets and welcome to my blog! =)

As you can tell from my About page, I’m a Computer Science Master Student. What this means is that this blog will be my geeky corner of the internet. My posts will probably be centered around projects of mine, code snippets, tutorials, ideas, etc… mainly developer related content. I may also drop some comments about some related keynotes and presentations, or just ramble about something that’s stuck in my head.

Whatever happens in this blog, I hope you enjoy your stay and I hope I can keep this interesting enough to get you to come back sometime =P

Well, there it is, my “Hello World” post.

Stay tuned..