Reputation: 5246
Bit of a doozy here. I've got various COM exposed systems and I've implemented Google maps (v3) into my .net software. What I'm trying to do now, is that when a user edits a polygon (defining an area), I send back all path points to .net for storing into our database.
My problem is that .Net knows that the JS array I pass back is X elements in size, but for the life of me I can't figure out how to reference the values while iterating through the array.
Here's the .NET (VB) method I'm using from JS with window.external
Public Sub AreaPointMoved(ByRef obj As Object, ByVal s As String)
MsgBox(s) ' contains a string of lat/lngs from JS
MsgBox(obj.length)
For i As Integer = 0 To obj.length
MsgBox(obj(i).lat & ", " & obj(i).lng) ' this doesn't work
'MsgBox(obj.lat & ", " & obj.lng) ' this doesn't work
Next
End Sub
And the JS that's sending stuff back upon the set_at
event being triggered:
function DrawAreaOverlay(area, col)
{
var coordsString = "";
var areaCoords = [];
overlayLayer[overlayCount] = new Array();
for(var j=0; j<area.Count; j++)
{
areaCoords.push(new google.maps.LatLng(area.Item(j).lng, area.Item(j).lat));
}
var poly = new google.maps.Polygon({
paths: areaCoords,
strokeColor: col,
strokOpacity: 0.35,
strokeWeight: 2,
fillColor: col,
fillOpacity: 0.25,
geodesic: false,
editable: canEdit,
draggable: canDrag,
map: map
});
overlayLayer[overlayCount].push(poly);
poly.getPaths().forEach(function(path, index){
google.maps.event.addListener(path, 'set_at', function(){
var arrayOfPoints = new Array();
var g = new Array();
arrayOfPoints = poly.getPath();
coordsString = "";
for(var i=0; i<arrayOfPoints.length; i++)
{
//simpleArray[i] = poly.getPath().getAt(i).lat() + ", " + poly.getPath().getAt(i).lng();
geoObj = new Object();
geoObj.lat = poly.getPath().getAt(i).lat();
geoObj.lng = poly.getPath().getAt(i).lng();
g.push(geoObj);
coordsString += poly.getPath().getAt(i).lat() + ", " + poly.getPath().getAt(i).lng() + "|";
}
window.external.AreaPointMoved(g, coordsString);
//alert(path.getLength());
});
});
}
I'm really confused. Getting objects from .net to JS was a doddle. But I can't for the life of me figure out what I'm doing wrong on the reverse :(
Cheers.
Upvotes: 0
Views: 2372
Reputation: 9494
According to answer like this, you have two options at your disposal for interacting with non-primitive arguments with calls to your ObjectForScripting
. This Connect thread says you should use a dynamic
as the argument type.
To my surprise, I learned that VB.NET doesn't have a an equivalent to C#'s dynamic keyword. Apparently Option Strict Off
and Option Infer On
accomplish the same ends:
Option Strict Off
Option Infer On
Public Sub AreaPointMoved(ByRef obj As Object, ByVal s As String)
For i As Integer = 0 To obj.length
'late binding to .lat and .lng should work now
' open Debug > Windows > Immediate
Debug.Print(obj(i).lat)
Debug.Print(obj(i).lng)
Next
End Sub
This is untested as I can't easily test any of this code. If this doesn't work, the second hail mary is using reflection to invoke the property:
Public Sub AreaPointMoved(ByRef obj As Object, ByVal s As String)
Dim lat As Double
Dim lng As Double
For i As Integer = 0 To obj.length
lat = obj(i).GetType().InvokeMember("lat", BindingFlags.InvokeMethod, Nothing, obj(i), Nothing)
lng = obj(i).GetType().InvokeMember("lng", BindingFlags.InvokeMethod, Nothing, obj(i), Nothing)
' view in Debug > Windows > Immediate
Debug.Print(lat)
Debug.Print(lng)
Next
End Sub
Forgive my VB.NET for any syntax errors. My skills translating C# to VB.NET are rusty at best.
Have you thought about using an array of arrays of doubles? You should not need an object property just to pass coordinates:
Public Sub AreaPointMoved(ByVal coordinates()() As Double)
End Sub
for(var i=0; i<arrayOfPoints.length; i++)
{
g.push([poly.getPath().getAt(i).lat(), poly.getPath().getAt(i).lng()]);
}
window.external.AreaPointMoved(g);
Hopefully one of these will help you sort this out. Good luck!
Sidebar: I highly recommend using Chromium Embedded Framework (CEF) or possibly Awesomium over the Windows WebBrowser control (which is a COM interop wrapper around Internet Explorer). Embedding Google Maps into a desktop app is going to be way smoother with a browser based on Chromium over IE. Both CEF and Awesomium have much richer ways to accomplish bi-directional calls between .Net IL and Javascript. You are having a hard time with the window.external
and WebBrowser.ObjectForScripting
simply because it is a crappy API for anything serious.
Upvotes: 1