Bootstrap

【WPF嵌套vue3】6. .netcore 6.0 WPF CefSharp加载本地的vue3项目,并互相调用方法

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方法传参,并对外封装成接口)
实际就是个小外挂盒子,模拟用户操作,来实现各种功能

;