2014-01-28 2 views
0

Немного о doozy здесь. У меня есть различные открытые системы COM, и я внедрил карты Google (v3) в свое программное обеспечение .net. То, что я пытаюсь сделать сейчас, заключается в том, что когда пользователь редактирует многоугольник (определяя область), я отправляю обратно все точки пути в .net для хранения в нашей базе данных.Массив объектов JS для VB.Net

Моя проблема в том, что .Net знает, что массив JS, который я передаю назад, является X-элементами по размеру, но для жизни я не могу понять, как ссылаться на значения при итерации по массиву.

Вот метод .NET (VB) Я использую от JS с 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 

И JS, который посылает материал обратно на set_at событии срабатывает:

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()); 
      }); 
     }); 
    } 

Я я действительно смущен. Получение объектов из .net в JS было неудачей. Но я не могу за жизнь мне понять, что я делаю неправильно на реверсе :(

Приветствий.

+0

Что делать, если вы положили точку останова на MsgBox и проверили, что там? – EaterOfCode

+0

Дисплеи: System .__ COMObject - но не позволяйте мне видеть любые поля или свойства любого типа. – LokiSinclair

+0

Попробуйте использовать obj [i] вместо obj (i) – kcak11

ответ

1

Согласно ответу like this, у вас есть два варианта в вашем распоряжении для взаимодействия с не- . примитивные аргументы с вызовами вашего ObjectForScriptingThis Connect thread говорит, что вы должны использовать dynamic как тип аргумента

к моему удивлению, я узнал that VB.NET doesn't have a an equivalent to C#'s dynamic keyword Видимо Option Strict Off и Option Infer On достижения тех же целей:..

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 

Это не проверено, так как я не могу легко проверить этот код. Если это не работает, второй Богородица является using reflection вызвать свойство:

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 

Простите мой VB.NET за любые ошибки синтаксиса. Мои навыки перевода C# на VB.NET в лучшем случае ржавые.

Задумывались ли вы об использовании массива парных пар? Вам не нужно свойство объекта только передать координаты:

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); 

Надеюсь, один из них поможет вам разобраться в этом. Удачи!


Sidebar: Я настоятельно рекомендую использовать Chromium Embedded Framework (CEF) или, возможно, Awesomium над управлением WebBrowser Windows (который является COM Interop оберткой Internet Explorer). Включение Google Maps в настольное приложение будет более плавным с браузером на основе Chromium over IE. И CEF, и Awesomium имеют гораздо более богатые возможности для выполнения двунаправленных вызовов между .Net IL и Javascript. У вас есть трудное время с window.external и WebBrowser.ObjectForScripting просто потому, что это скверный API для чего-то серьезного.

+0

Согласился, что обертка браузера IE не слишком удобна в использовании! Но в настоящий момент это прототип. Спасибо за ссылки, я посмотрю и посмотрю, что я могу сделать. Большая часть работы grunt выполняется внутри самой JS, поэтому, надеюсь, это будет просто перенос элементов управления и другой способ загрузки содержимого файловой системы. Ура! +1 – LokiSinclair

Смежные вопросы