vue项目打包
Vue 项目打包我就不说了,webpack或者vite打包即可,打包后获取一个本地程序
实际在CefSharp加载中
可以把vue运行起来,使用localhost
也可以直接使用程序的绝对路径,直接加载打包好的html文件
以下方法二选一即可
//直接加载vue本地文件
this.browser.initBrowser(System.AppDomain.CurrentDomain.BaseDirectory + "Resources/vue/index.html");
//直接加载localhost本地程序
this.browser.initBrowser(@"http://localhost:1234");
这个时候程序再运行,即实现了wpf+vue项目的嵌套展示了
两者之间的数据交互,我们接着操作
vue代码调用wpf方法
- 首先,将相关的方法进行绑定
public void initBrowser(string apiUrl)
{
CefSettings cefSettings = new CefSettings();
cefSettings.CefCommandLineArgs.Add("no-proxy-server", "1");
cefSettings.CefCommandLineArgs.Add("disable-gpu", "1");
cefSettings.CefCommandLineArgs.Add("proxy-server", "ProxyAddress");
cefSettings.CefCommandLineArgs.Add("disable-pinch", "1");
cefSettings.CefCommandLineArgs.Add("enable-media-stream", "1");
cefSettings.CefCommandLineArgs.Add("enable-system-flash", "1");
cefSettings.CefCommandLineArgs.Add("enable-speech-input", "1");
cefWebBrowser = new ChromiumWebBrowser();
//js调用启用
cefWebBrowser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
this.cefWebBrowser.KeyboardHandler = new CEFKeyBoardHander();
this.cefWebBrowser.Visibility = Visibility.Visible;
this.cefWebBrowser.Load(apiUrl);
//绑定方法
ClientAsyncProxy objectToBind = new ClientAsyncProxy(this.cefWebBrowser);
//注册方法供vue调用
this.cefWebBrowser.JavascriptObjectRepository.Register("clientAsyncProxy", objectToBind, BindingOptions.DefaultBinder);
this.cefWebBrowser.FrameLoadEnd += new EventHandler<FrameLoadEndEventArgs>(this.CefWebBrowser_FrameLoadEnd);
this.cefWebBrowserGrid.Children.Add(this.cefWebBrowser);
}
using CefSharp.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WPF.Photo.Startup
{
public abstract class IProxy
{
public ChromiumWebBrowser cefWebBrowser;
public IProxy(ChromiumWebBrowser browser)
{
this.cefWebBrowser = browser;
}
}
}
using CefSharp;
using CefSharp.Wpf;
using Prism.Services.Dialogs;
using System;
using System.Buffers.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Unity;
using WPF.Net.Common;
using WPF.Photo.Common;
using WPF.Photo.Core;
using WPF.Photo.Core.Model;
using WPF.Photo.Startup.HandlerPage;
using static System.Resources.ResXFileRef;
namespace WPF.Photo.Startup
{
public class ClientAsyncProxy : IProxy
{
public ClientAsyncProxy(ChromiumWebBrowser browser) : base(browser)
{
}
public void playVoice(string voice, IJavascriptCallback sdkCallBackAction)
{
ResultMsg msg = new ResultMsg()
{
Content = "语音播放失败"
};
try
{
string filePath = "";
switch (voice.ToLower())
{
case "photomp3"://相机咔嚓声
filePath = AudioConst.PhotoMP3;
break;
}
if (!string.IsNullOrEmpty(filePath))
{
AudioTools.PlayVideoFile(filePath);
msg.Content = "播放成功";
msg.Code=Result.Success;
}
}
catch (Exception ex)
{
Logger.Error(ex, "语音播放异常!");
msg.Content = "语音播放异常!";
}
finally
{
sdkCallBackAction.ExecuteAsync(msg);
}
}
}
}
接下来在vue中进行调用
我这个其实对外进行了一层封装,只需要直接调用
window.clientAsyncProxy.palyVoice(xx,xxx) 即可直接调用
xx是参数,xxx是后端c#返回的数据
clientAsyncProxy对应this.cefWebBrowser.JavascriptObjectRepository.Register绑定的第一个参数
export const PlayVoice = (voice: string, action?: (res: any) => void) => {
window.clientAsyncProxy.playVoice(voice, (res: any) => {
if (action != undefined) {
action(res)
}
})
}
wpf主动调用vue方法
wpf中可以直接使用非UI现场直接调用vue的方法
Dispatcher.BeginInvoke(new Action(delegate
{
if (this.browser.cefWebBrowser.IsBrowserInitialized)
{
this.browser.cefWebBrowser.GetBrowser().MainFrame
.ExecuteJavaScriptAsync("document.dispatchEvent(new CustomEvent('test', { detail: { para: '" + JsonTools.ObjToStr(info) + "' } }));");
}
}));
vue的接受方法如下
document.addEventListener("test", (ev: any) => {
let para= JSON.parse(ev.detail.para)
cosnole.log(para)
})
总结
到这里 vue和wpf的交互就结束了,即完成展示,也完成了双方的数据交互,这个坑我就算是填完了,加载vue本质上就是加载html+js,和vue3可以交互,当然也就可以和vue2、javascript交互,当初我写的时候 vue3交互的方法内容比较少,也希望大家可以借鉴看一下
本质就是 wpf嵌套浏览器,使用浏览器组件显示网页,并和网页上的js进行方法调用
ps:我以前做过类似的程序,wpf嵌套一个功能网页,然后各种调用它的js方法(因为那个公司没有接口,我直接调用他们的js方法传参,并对外封装成接口)
实际就是个小外挂盒子,模拟用户操作,来实现各种功能