WPF调用百度地图API

2 篇文章 0 订阅

WPF调用百度地图API

接触WPF时间不长,一直在学习的状态,偶尔研究一个功能实现。本示例用的是WPF+WebView2控件,通过WebView2内嵌成品HTML页,再用WPF窗体展示,适合C端窗体按钮的触发事件。先看一下最终效果:

在这里插入图片描述

创建HTML文件

我是随意在WPF项目中创建的HTML文件,然后通过百度地图API的示例写出

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>行政区划归属获取</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <style>
        body,
        html,
        #container {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            font-family: "微软雅黑";
        }

        .info {
            z-index: 999;
            width: auto;
            min-width: 22rem;
            padding: .75rem 1.25rem;
            margin-left: 1.25rem;
            position: fixed;
            top: 1rem;
            background-color: #fff;
            border-radius: .25rem;
            font-size: 14px;
            color: #666;
            box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
        }
    </style>
    <script type="text/javascript" src="https://api.map.baidu.com/api?type=webgl&v=1.0&ak=你的密钥"></script>
</head>
<body>
    <div id="container"></div>

</body>
</html>
<script>
    var map = new BMapGL.Map('container');
    var point = new BMapGL.Point(116.404, 39.915);
    map.centerAndZoom(point, 15);
    map.enableScrollWheelZoom(true);

    var marker;
    var HostObject = window.chrome.webview.hostObjects.ScriptCallbackObject;
    var gc;
    //自动定位
    var geolocation = new BMapGL.Geolocation();
    geolocation.getCurrentPosition(function (r) {
        if (this.getStatus() == BMAP_STATUS_SUCCESS) {
            marker = new BMapGL.Marker(r.point, {
                enableDragging: true
            });
            map.addOverlay(marker);
            map.panTo(r.point);

            point = new BMapGL.Point(r.point.lng, r.point.lat);
            map.centerAndZoom(point, 15);


            gc = new BMapGL.Geocoder();
            gc.getLocation(point, function (rs) {
                HostObject.ReceivingMessage(rs.addressComponents.province + rs.addressComponents.city + rs.addressComponents.district);
            });
            //alert('您的位置:' + r.point.lng + ',' + r.point.lat);
        }
        else {
            alert('failed' + this.getStatus());
        }
    });

    //点击事件
    map.addEventListener('click', function (e) {
        var point = new BMapGL.Point(e.latlng.lng, e.latlng.lat);

        //清除覆盖物
        map.clearOverlays();
        // 创建点标记
        enableDragging: true
        marker = new BMapGL.Marker(point, {
        });
        map.addOverlay(marker);
        map.panTo(point);

        gc = new BMapGL.Geocoder();
        gc.getLocation(point, function (rs) {
            var opts = {
                title: '行政区划归属',
                width: 220,
                height: 92
            };
            var infoStr = '<div>省:' + rs.addressComponents.province + '</div>'
                + '<div>市:' + rs.addressComponents.city + '</div>'
                + '<div>区:' + rs.addressComponents.district + '</div>';
            var infoWindow = new BMapGL.InfoWindow(infoStr, opts);
            map.openInfoWindow(infoWindow, point);
            HostObject.ReceivingMessage(rs.addressComponents.province + rs.addressComponents.city + rs.addressComponents.district);
        });
    });

    //地名查询定位
    function LocateByName(msg) {
        //清除覆盖物
        map.clearOverlays();

        var local = new BMapGL.LocalSearch(map, {
            renderOptions: { map: map }
        });
        local.search(msg);

        gc = new BMapGL.Geocoder();
        gc.getLocation(point, function (rs) {
            HostObject.ReceivingMessage(rs.addressComponents.province + rs.addressComponents.city + rs.addressComponents.district);
        });
    }
</script>

引入WebView2控件包

在这里插入图片描述

xaml文件的设计

<Window x:Class="WPF.Map.LoadDemo.LocationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        xmlns:local="clr-namespace:WPF.Map.LoadDemo"
        WindowStartupLocation="CenterScreen"
        mc:Ignorable="d"
        Title="选择位置" Height="450" Width="800" Loaded="Window_Loaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <TextBox Grid.Row="0" Name="LocationTextBox" Text="{Binding Value}" Width="250" Height="25" HorizontalAlignment="Left" Margin="10" VerticalAlignment="Center" />
            <Button Grid.Row="0" Name="LocationButton" Content="查询" Width="80" Height="20" HorizontalAlignment="Left"  Click="LocationButton_ClickAsync"/>
        </StackPanel>

        <wv2:WebView2 Grid.Row="1" Name="webView"/>
    </Grid>
</Window>

注意此处的WebView2包引入
在这里插入图片描述

后台代码

自定义交互类

[ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class ScriptCallbackObject : INotifyPropertyChanged
    {
        private string _value;

        public event PropertyChangedEventHandler? PropertyChanged;

        public string Value
        {
            get { return _value; }
            set
            {
                _value = value;
                OnPropertyChanged(nameof(Value));
            }
        }

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public void ShowingMessageBox(string arg)
        {
            MessageBox.Show(arg);
        }
        public async void ReceivingMessage(string arg)
        {
            Value = arg;
        }
    }

自定义的交互类,必须标记 [ClassInterface(ClassInterfaceType.AutoDual)]、[ComVisible(true)] 特性,否则JS无法访问到该类

初始化并在WebView控件中添加本地HTML文件

  private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
            webView.EnsureCoreWebView2Async();
        }

        private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {
            if (webView != null && webView.CoreWebView2 != null)
            {
                SCO = new ScriptCallbackObject();
                this.DataContext = SCO;
                //注册csobj脚本c#互操作
                webView.CoreWebView2.AddHostObjectToScript("ScriptCallbackObject", _sco);
                //加载页面
                string rootPath = @"E:\Demo\WPFDemo\WPF.Map.LoadDemo\WPF.Map.LoadDemo";// Environment.CurrentDirectory;
                string filepath = System.IO.Path.Combine(rootPath, "HTMLPage5.html");
                webView.Source = new Uri(filepath);
            }
        }

C#后台调用HTML中的JS函数

  private async void LocationButton_ClickAsync(object sender, RoutedEventArgs e)
        {
            if (webView != null && webView.CoreWebView2 != null)
            {
                await webView.CoreWebView2.ExecuteScriptAsync($"LocateByName('{this.LocationTextBox.Text}')");
            }
        }

后台整体代码

using Microsoft.Web.WebView2.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WPF.Map.LoadDemo
{
    /// <summary>
    /// LocationView.xaml 的交互逻辑
    /// </summary>
    public partial class LocationView : Window
    {
        private ScriptCallbackObject _sco;

        public ScriptCallbackObject SCO
        {
            get { return _sco; }
            set { _sco = value; }
        }

        public LocationView()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
            webView.EnsureCoreWebView2Async();
        }

        private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {
            if (webView != null && webView.CoreWebView2 != null)
            {
                SCO = new ScriptCallbackObject();
                this.DataContext = SCO;
                //注册csobj脚本c#互操作
                webView.CoreWebView2.AddHostObjectToScript("ScriptCallbackObject", _sco);
                注册全局变量csobj
                //webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var csobj = window.chrome.webview.hostObjects.csobj;");
                //webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var csobj_sync= window.chrome.webview.hostObjects.sync.csobj;");

                //加载页面
                string rootPath = @"E:\Demo\WPFDemo\WPF.Map.LoadDemo\WPF.Map.LoadDemo";// Environment.CurrentDirectory;
                string filepath = System.IO.Path.Combine(rootPath, "HTMLPage5.html");
                webView.Source = new Uri(filepath);

                //this.LocationTextBox.Text = _sco.Value;
            }
        }

        private async void LocationButton_ClickAsync(object sender, RoutedEventArgs e)
        {
            if (webView != null && webView.CoreWebView2 != null)
            {
                await webView.CoreWebView2.ExecuteScriptAsync($"LocateByName('{this.LocationTextBox.Text}')");
            }
        }
    }

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class ScriptCallbackObject : INotifyPropertyChanged
    {
        private string _value;

        public event PropertyChangedEventHandler? PropertyChanged;

        public string Value
        {
            get { return _value; }
            set
            {
                _value = value;
                OnPropertyChanged(nameof(Value));
            }
        }

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public void ShowingMessageBox(string arg)
        {
            MessageBox.Show(arg);
        }
        public async void ReceivingMessage(string arg)
        {
            Value = arg;
        }
    }
}

工作也有些年头了,但也是才意识到记录的重要性,不仅自己可以温故,或许还能帮到别人,本人初学WPF,浅浅应用,如有不足,欢迎指正。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值