WPF调用百度地图API

WPF调用百度地图API

  • WPF调用百度地图API
    • 创建HTML文件
    • 引入WebView2控件包
    • xaml文件的设计
    • 后台代码
      • 自定义交互类
      • 初始化并在WebView控件中添加本地HTML文件
      • C#后台调用HTML中的JS函数
    • 后台整体代码

WPF调用百度地图API

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

WPF调用百度地图API_第1张图片

创建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 = '
省:' + rs.addressComponents.province + '
'
+ '
市:' + rs.addressComponents.city + '
'
+ '
区:' + rs.addressComponents.district + '
'
; 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控件包

WPF调用百度地图API_第2张图片

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包引入
WPF调用百度地图API_第3张图片

后台代码

自定义交互类

[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
{
    /// 
    /// LocationView.xaml 的交互逻辑
    /// 
    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,浅浅应用,如有不足,欢迎指正。

你可能感兴趣的:(.Net,WPF,wpf,c#,visual,studio,百度,.net)