【问题标题】:How to pass information from a WPF app to an HTML page如何将信息从 WPF 应用程序传递到 HTML 页面
【发布时间】:2019-05-24 18:04:03
【问题描述】:

我有一个 WPF 应用程序,它查找纬度和经度位置,并将它们显示给应用程序内的用户。该应用程序有一个按钮,当单击该按钮时,应该使用 Google 地图 API 打开地图并使用标记在地图上显示这些位置。

我在一个 HTML 中得到了这个下面的脚本,到目前为止,它只是在一个固定位置打开一个地图并只显示一个示例标记。

<script>
  function initMap() {
    let myLatLng = {lat: -25.363, lng: 131.044};

    let map = new google.maps.Map(document.getElementById('map'), {
      zoom: 4,
      center: myLatLng
    });

    let marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      title: 'TITLE!'
    });
  }
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=<myKey>&callback=initMap">
</script>

所以我知道,为了打开页面本身,我需要做的就是:

System.Diagnostics.Process.Start(pathToHtmlFile);

但是我怎样才能将我在 WPF 端找到的位置传递给 JS initMap 函数?

【问题讨论】:

  • 如果我没记错的话System.Diagnostics.Process.Start(pathToHtmlFile); 将简单地使用.html 文件的系统默认处理程序——在大多数情况下这是一个浏览器。也许您可以尝试将 lat/lng 附加为查询字符串参数并在 JS 中使用它。
  • @NickZA 你能展示一个代码示例吗
  • Storms 的回答似乎是合理的,他们似乎打败了我 :)
  • 我创建了第二个答案,它不一定直接适合您的原始问题(它不是传递信息,而是嵌入它),但它确实满足了通过 cmets 描述和暗示的要求。

标签: javascript c# html wpf google-maps


【解决方案1】:

在文件打开命令中使用 GET 语义。

您必须使用 URI 作为命令:"file://pathToHtmlFile?lat=" + Lat + "&amp;lng=" + Long"

在脚本块中添加一个函数:

function get(name){
   if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
      return decodeURIComponent(name[1]);

并调用 lat 和 lng 的 get 函数。

【讨论】:

  • 如果我有几个需要通过的地点怎么办?我如何通过并阅读所有内容?
  • @YonatanNir,在 URI 末尾添加更多选项:"file://pathToHtmlFile?lat=" + Lat + "&amp;lng=" + Long&amp;lat1=" + Lat1 + "&amp;lng1=" + Long1"... 有一个基于 url 长度的最大数量(浏览器限制)。
  • 能否也展示一个如何从 WPF 端传递 POST 参数的示例?
  • @YonatanNir,据我所知,POST 方法需要网络服务器。
  • 那么从客户端内部,GET 是唯一可行的方法吗?
【解决方案2】:

另一种方法是动态构建 html 文件。这支持任意数量的标记(最多 256 到 ~5000+,取决于内存和 API 限制)。

HTML 文件分成两部分,顶部和底部(请参见下面的代码),在其中需要插入数据。

  1. 将文件中的“顶部”加载到变量Output 中,并在地图中心附加地图关闭数据标签} );

  2. 然后循环遍历每个标记,为每个定义的标记添加一个新的标记 Javascript 变量 marker0marker1...。然后将此代码附加到Output 变量中。

  3. “底部”附加到Output 变量并保存到输出文件中。这个“结束”文件用} 和脚本标签关闭了打开的function initMap(){,并包含带有回调的谷歌地图的加载脚本。

  4. 这个保存的文件然后被浏览器打开(不需要传递数据)。

将 html 文件的顶部放在一个名为 topTemplate.html 的新项目文件中(将 Properties: compile options 设置为 none 并 Copy to output directory: copy if newer):

<script>
  function initMap() {

    let map = new google.maps.Map(document.getElementById('map'), {
      zoom: 4,
      center:     

注意:我从代码中删除了let myLatLng = {lat: -25.363, lng: 131.044};,我对其进行“硬编码”(将在 C# 中定义)以简化段的划分(2 vs 3)。

还有bottomTemplate.html中的最后一部分(属性设置与上述文件相同):

    }
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=<myKey>&callback=initMap">
</script>

然后在 WPF 应用程序中:

为了方便起见,我定义了一个 struct 来保存标记,并使用辅助函数来构建输出字符串。

public struct Marker
{
    public float Lat;
    public float Lng;
    public string Title;

    public Marker(float lat,float lng, string title)
    {
        Lat = lat;
        Lng = lng;
        Title = title;
    }
    
    public string BuildHTML(int nameAppend)
    {
        return  String.Format("\n let marker{0} = new google.maps.Marker({{ position: {{lat: {1:###0.0####}, lng: {2:###0.0####}}}, map: map, title: '{3}'}}); \n", nameAppend, Lat, Lng, Title);
    }
}

{{}}{} 的字面形式。 ###0.0### 将实际数字返回到小数点后四位。如果没有此代码,浮点数可以用科学计数法值表示或本地化为“,”分隔符,其中任何一个都可能与 API 不兼容。如果需要,“#”可以扩展到小数点右侧以提高精度。

以下代码大多放在打开文件的Method中,见cmets:

// at top of file add:
using System.IO;
// rest of namespace, class definition and method opening

// Assumes all of the markers are stored in: List<Markers> markers = new List<Markers>();
// and the center of the map is stored in float lat; and float lng;

string Output = File.ReadAllText("topTemplate.html");
// Since the topTemplate ended with "center: " we must fill in the values and close the request.
Output += String.Format("{{lat: {1:###0.0####}, lng: {2:###0.0####}}} }} );\n",lat, lng);
int index = 0;
foreach(var item in markers)
{
    Output += item.BuildHTML(index++); //adds 1+ to the marker0 to form another variable marker1 ... for each marker variable name.
}
Output += "\n"; //add a vertical space to the Output. Before adding the end:
Output += File.ReadAllText("bottomTemplate.html");

 // we will assume pathToHtmlFile contains a valid filename and is in a writable directory. If not, move the path to %ProgramData% or %temp%.

File.WriteAllText(pathToHtmlFile, Output); // will overwrite the file if it exists.
// start the browser. 
System.Diagnostics.Process.Start(pathToHtmlFile);

// The remainder of the file(method remainder and close, class remainder and close...)

浏览器 may not run 在客户端计算机上的启动,因为“此成员(Process.Start)不能被部分受信任的代码使用。”这是实际答案的旁注。请务必使用安装程序。

生成的文件中的缩进将不正确,因为 Javascript 是独立于空白的(所有空白(换行符、制表符和多个空格都减少为一个空格)),这不是问题。

标记列表必须声明为(List markers = new List();)作为类级别变量或在方法的顶部。

使用markers.Add(new Marker(Latitude, Longitude, Title)); 将“纬度、经度和标题”替换为它们各自的值(或包含它们的变量),以添加每个标记;在调用上面的“方法”之前。

【讨论】:

    猜你喜欢
    • 2011-01-16
    • 2021-10-17
    • 1970-01-01
    • 2012-09-17
    • 2019-10-05
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    相关资源
    最近更新 更多