Daniel Underwood
Daniel Underwood

Reputation: 2271

Using Javascript for Google Maps API from WPF

I am creating an application that interfaces with Google's Maps API v3. My current approach is using a WebBrowser control by WebBrowser.Navigate("Map.html"). This is working correctly at the moment; however, I am also aware of WebBrowser.InvokeScript(). I have seen this used to execute a javascript function, but I would like to have something like the following structure:

APICalls.js - Contains different functions that can be called, or even separated out into a file for each function if necessary.

MapInterface.cs

WebBrowser.InvokeScript("APICalls.js", args) - Or control the javascript variables directly.

I have seen the InvokeScript method used, but none of the examples gave any detail to the source of the function, so I'm not sure if it was calling it from an html file or js file. Is it possible to have a structure like this, or a similarly organized structure, rather than creating an html file with javascript in each one and using Navigate()?

Additionally, are there any easier ways to use Google Maps with WPF. I checked around, but all of the resources I found were at least 2-3 years old, which I believe is older than the newest version of the maps API.

Upvotes: 2

Views: 3183

Answers (1)

noseratio
noseratio

Reputation: 61736

I can't suggest a better way of using Google Maps API with WPF (although I'm sure it exists), but I can try to answer the rest of the question.

  • First, make sure to enable FEATURE_BROWSER_EMULATION for your WebBrowser app, so Google Maps API recognizes is it as modern HTML5-capable browser.

  • Then, navigate to your "Map.html" page and let it finish loading. Here's how it can be done using async/await (the code is for the WinForms version of WebBrowser control, but the concept remains the same).

  • You can have your APICalls.js as a separate local file, but you'd need to create and populate a <script> element for it from C#. You do it once for the session.

Example:

var scriptText = File.ReadAllText("APICalls.js");
dynamic htmlDocument = webBrowser.Document;
var script = htmlDocument.createElement("script");
script.type = "text/javascript";
script.appendChild(htmlDocument.createTextNode(scriptText));
htmlDocument.body.appendChild(script);

For example, your JavaScript entry point function in APICalls.js may look like this:

(function() {
    window.callMeFromCsharp = function(arg1, arg2) {
        window.alert(arg1 + ", " +arg2);
    } 
})();

Which you could call from C# like this:

webBrowser.InvokeScript("callMeFromCsharp", "Hello", "World!");

[UPDATE] If you're looking for a bit more modular or object-oriented approach, you can utilize the dynamic feature of C#. Example:

JavaScript:

(function() {
    window.apiObject = function() {
        return {
            property: "I'm a property",
            Method1: function(arg) { alert("I'm method 1, " + arg); },
            Method2: function() { return "I'm method 2"; }
        };
    } 
})();

C#:

dynamic apiObject = webBrowser.InvokeScript("apiObject");
string property = apiObject.property;
MessageBox.Show(property);
apiObject.Method1("Hello!");
MessageBox.Show(apiObject.Method2());

Upvotes: 4

Related Questions