接触WPF时间不长,一直在学习的状态,偶尔研究一个功能实现。本示例用的是WPF+WebView2控件,通过WebView2内嵌成品HTML页,再用WPF窗体展示,适合C端窗体按钮的触发事件。先看一下最终效果:
我是随意在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>
<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>
[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无法访问到该类
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);
}
}
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,浅浅应用,如有不足,欢迎指正。