【问题标题】:Array of JS objects to VB.NetVB.Net 的 JS 对象数组
【发布时间】:2014-02-19 18:16:09
【问题描述】:

这里有点笨拙。我有各种暴露 COM 的系统,并且在我的 .net 软件中实现了 Google 地图 (v3)。我现在要做的是,当用户编辑多边形(定义区域)时,我将所有路径点发送回 .net 以存储到我们的数据库中。

我的问题是 .Net 知道我传回的 JS 数组的大小是 X 个元素,但对于我来说,我无法弄清楚如何在遍历数组时引用这些值。

这是我在 JS 中使用 window.external 的 .NET (VB) 方法

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

以及在set_at 事件被触发时发回内容的 JS:

    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 是一件轻而易举的事。但是我一生都无法弄清楚我做错了什么:(

干杯。

【问题讨论】:

  • 如果你在 MsgBox 上放一个断点并检查里面有什么?
  • 显示:System.__COMObject - 但不会让我看到任何类型的字段或属性。
  • 尝试使用 obj[i] 而不是 obj(i)
  • 甚至不编译。 “需要标识符。”使用:obj[0].lat - 我会用字符串解决它。老学校的方式!我只是希望,因为将一个可枚举数组传递给 JS 很简单,所以从 JS 中返回和迭代一个数组会很容易。
  • 类似的问答:stackoverflow.com/a/20943173/1768303。代码用 C# 编写,但可以从 VB.NET 使用相同的反射 API。

标签: javascript arrays vb.net google-maps-api-3


【解决方案1】:

根据like this 的回答,您有两种选择可以通过调用ObjectForScripting 与非原始参数进行交互。 This Connect thread 表示您应该使用 dynamic 作为参数类型。

令我惊讶的是,我学会了that VB.NET doesn't have a an equivalent to C#'s dynamic keyword。显然Option Strict OffOption 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);

希望其中之一可以帮助您解决这个问题。祝你好运!


侧边栏:我强烈建议在 Windows WebBrowser 控件(它是 Internet Explorer 的 COM 互操作包装器)上使用 Chromium Embedded Framework (CEF)Awesomium。使用基于 Chromium over IE 的浏览器将谷歌地图嵌入桌面应用程序将更加顺畅。 CEF 和 Awesomium 都有更丰富的方式来完成 .Net IL 和 Javascript 之间的双向调用。您很难使用 window.externalWebBrowser.ObjectForScripting 仅仅是因为它是一个糟糕的 API,用于任何严肃的事情。

【讨论】:

  • 同意 IE 浏览器包装器使用起来并不过分愉快!但它目前主要是一个原型。感谢您的链接,我会看看我能做些什么。大多数繁重的工作都是在 JS 本身内完成的,所以希望这只是迁移控件和加载文件系统内容的不同方式的情况。干杯! +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多