C#CefSharpを使ったウェブページの埋め込み-C #とJSの相互作用の例

C#CefSharpを使ったウェブページの埋め込み-C #とJSの相互作用の例

クライアント側にウェブページを埋め込む必要がありますか?CefSharpは良い選択かもしれない!

最后更新 2023/03/27 22:43
沙漠尽头的狼
预计阅读 7 分钟
分类
.NET
标签
.NET C# CefSharp

こんにちは、私は砂漠の果ての狼です。

この記事では、CefSharpを使用してC#WPFでWebページを埋め込む方法を説明し、C#とWebページ(JS)の相互作用を示す簡単な例を提供します。

1.構築ステップの例

先给出本文示例代码:WpfWithCefSharpDemo

1. プロジェクトを作成する

Winformプロジェクトと同様に、“WpfWithCefSharpDemo”という名前のWPFプロジェクトを作成します。

2. Webページを作成する

嵌入的网页可以是在线的(即给出一个URL),也可以是一个离线的HTML网页,本文为了演示,在工程里直接创建网页test.html,属性设置生成操作内容复制到输出目录如果较新则复制

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>CefSharp测试</title>
    <script>
        // 测试在Web中调用C#的方法
        function callCSharpMethod() {
            window.cefSharpExample.testMethod("来自JS的调用");
        }

        // 测试C#调用JS的方法,只传递一个普通的字符串
        function displayMessage(message) {
            alert(message);
        }

        // 接收C#传递过来的JSON对象,并以表格形式展示在页面上
        function displayJson(json) {
            var obj = JSON.parse(json);
            var html = "<table border='1'>";
            for (var prop in obj) {
                html += "<tr>";
                html += "<td>" + prop + "</td>"
                html += "<td>" + obj[prop] + "</td>"
                html += "</tr>"
            }
            html += "</table>";
            document.getElementById("jsonTable").innerHTML = html;
        }
    
    </script>
</head>
<body>
<h1>CefSharp测试</h1>
<button onclick="callCSharpMethod()">调用C#方法</button>
<div id="jsonTable"></div>
</body>
</html>

上記のコードは関連するコメントを提供しており、それは明確です:

  • JS方法callCSharpMethod:用于测试JS调用C#的方法,其中cefSharpExample为C#注册的一个对象,testMethod是其一个方法,JS中方法名首字母是小写(C#里按规则是大写),首字母这里有区别,要注意一下;
  • JS方法displayMessagedisplayJson:用于测试C#调用JS的方法,方法定义类似,前者入参是一个普通字符串,后者入参是一个JSON字符串。
  • div要素jsonTableはC#からのJSonオブジェクトデータを表示します。

3. CefSharpパッケージを追加

CefSharp.WpfをVisual StudioのNuGetパッケージマネージャで検索してインストールするCefSharp.Wpfパッケージをインストールします。

4. CefSharpコントロールを追加

MainWindow.xaml中引入CefSharp.Wpf命名空间(取别名为wpf,这里随意),将它的chromium控件加入到窗体中,顺带加几个测试按钮等:

<Window x:Class="WpfWithCefSharpDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
        mc:Ignorable="d"
        Title="WPF加载CefSharp测试" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="35"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="下面显示的是网页内容"></TextBlock>
        <Border Grid.Row="1" BorderBrush="DarkOrange" BorderThickness="2">
            <wpf:ChromiumWebBrowser x:Name="Browser" Loaded="Browser_OnLoaded">
            </wpf:ChromiumWebBrowser>

        </Border>
        <Border Margin="3 5" Grid.Row="2" BorderBrush="Blue" BorderThickness="2" VerticalAlignment="Center">
            <StackPanel Orientation="Horizontal" Height="35">
                <TextBlock Text="右侧按钮是WPF按钮" VerticalAlignment="Center" Margin="5 3"></TextBlock>
                <Button Content="调用JS方法" Click="CallJSFunc_Click" Height="30" Padding="10 2"></Button>
                <Button Content="C#传递Json对象到网页" Click="SendJsonToWeb_Click" Height="30" Padding="10 2"></Button>
            </StackPanel>
        </Border>
    </Grid>
</Window>

5. C#でのJSメソッドの呼び出し

MainWindow.xaml.cs里,添加相关控件的事件处理方法,即C#调用JS方法的相关代码:

using CefSharp;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
using System.Windows;

namespace WpfWithCefSharpDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // 允许以同步的方式注册C#的对象到JS中
            Browser.JavaScriptObjectRepository.Settings.LegacyBindingEnabled = true;
            CefSharpSettings.WcfEnabled = true;

            // 注册C#的对象到JS中的代码必须在Cef的Browser加载之前调用
            Browser.JavaScriptObjectRepository.Register("cefSharpExample", new CefSharpExample(), false,
                options: BindingOptions.DefaultBinder);
        }

        /// <summary>
        /// Cef浏览器控件加载完成后,加载网页内容,可以加载网页的Url,也可以加载网页内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Browser_OnLoaded(object sender, RoutedEventArgs e)
        {
            var htmlFile = $"{AppDomain.CurrentDomain.BaseDirectory}test.html";
            if (!File.Exists(htmlFile))
            {
                return;
            }

            var htmlContent = File.ReadAllText(htmlFile, Encoding.UTF8);
            Browser.LoadHtml(htmlContent);
        }

        /// <summary>
        /// C#里调用JS的一般方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CallJSFunc_Click(object sender, RoutedEventArgs e)
        {
            var jsCode = $"displayMessage('C#里的调用')";
            Browser.ExecuteScriptAsync(jsCode);
        }

        /// <summary>
        /// C#调用一个JS的方法,并传递一个JSON对象
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendJsonToWeb_Click(object sender, RoutedEventArgs e)
        {
            var jsonContent = new
            {
                Id = 1,
                Name = "沙漠尽头的狼",
                Age = 25,
                WebSite="https://dotnet9.com"
            };
            var jsonStr = JsonConvert.SerializeObject(jsonContent);

            // 传递Json对象,即传递一个JSON字符串,和前面的一个示例一样
            var jsCode = $"displayJson('{jsonStr}')";
            Browser.ExecuteScriptAsync(jsCode);
        }
    }

    public class CefSharpExample
    {
        public void TestMethod(string message)
        {
            Application.Current.Dispatcher.Invoke(() => { MessageBox.Show("JS里的调用"); });
        }
    }
}

CefSharpExample用于封装JS调用的类及方法定义,注意C#这里TestMethod方法名首字母是大写的,前面创建的HTML网页调用的该方法名首字母小写,再提醒一次,这里的区别要注意。

6. 効果の表示

JS调用C#的方法:黄色方框内显示的网页内容,点击HTML按钮调用C#方法测试。

C#调用JS的普通方法:蓝色方框内显示的WPF控件,点击WPF按钮调用JS方法测试。

C#传递Json对象给JS的方法:蓝色方框内,点击WPF按钮C#传递Json对象到网页测试。

II.概要

WPFまたはWinformネイティブのWebBrowserコントロールを使用したことがある場合は、WPFネイティブのWebBrowserコントロールとCefSharpの比較を行います(ChatGPT回答の結果)この記事を締めくくります。

WPFに付属するWebBrowserコントロールの利点:

  1. WebBrowserコントロールはWPFに組み込まれており、追加のライブラリやコンポーネントをインストールする必要はありません。

  2. WebBrowserコントロールはInternet Explorerカーネルに基づいているため、Windowsオペレーティングシステムとの自然な互換性と安定性があります。

  3. WebBrowserコントロールは、Navigating、Navigated、LoadCompletedなどのブラウザ関連イベントを多数提供し、ウェブページの読み込みとナビゲーションを制御し、フィードバックすることができます。

WPFに付属するWebBrowserコントロールの短所:

  1. WebBrowserコントロールは古いバージョンのIEカーネルを使用しており、最新のHTML 5、CSS 3などの標準をサポートしておらず、CefSharpよりもパフォーマンスが低い。

  2. WebBrowserコントロールのAPIは比較的少なく、ウェブサイトナビゲーションの傍受やカスタムレンダリングなどの高度な機能を実装することは困難です。

**CefSharpのメリット **

  1. CefSharpはChromiumプロジェクト上に構築されており、HTML 5、CSS 3などの最新のウェブ標準をサポートし、パフォーマンスも向上しています。

  2. CefSharpは豊富なAPIセットを提供しており、ウェブリクエストのカスタマイズ、ウェブナビゲーションのブロック、HTMLコンテンツの変更など、高度な機能を実装できます。

  3. CefSharpはマルチスレッドモデルとハードウェアアクセラレーションレンダリングを使用し、UIスレッドをブロックせず、安定性とセキュリティを向上させます。

CefSharpの欠点:

  1. CefSharpは追加のライブラリやコンポーネントをインストールする必要があり、開発が複雑になります。

  2. CefSharpは、高密度スクリーンでレンダリングする場合など、特定の状況下でパフォーマンスに問題が発生することがあります。

したがって、Webブラウザコントロールを選択するときは、特定のニーズに基づいて選択する必要があります。Webコンテンツを表示するだけで、高度な機能を必要としない場合は、WPFに付属のWebBrowserコントロールで十分です。しかし、カスタムネットワークリクエストやウェブナビゲーションの傍受など、複雑な機能を実装する必要がある場合は、CefSharpの方が適しているかもしれません。全体的に、CefSharpはWPFに付属するWebBrowserコントロールよりもはるかに強力でパフォーマンスが高いが、使用は比較的複雑である。

参考文献より:

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2023/04/25

CefSharpのカスタムキャッシュ実装

CefSharpのキャッシュ機能を使用すると、アプリケーションのパフォーマンスとユーザーエクスペリエンスを向上させ、ネットワークトラフィックとサーバー負荷を軽減し、オフラインアクセスをサポートすることができます。

继续阅读
同分类 / 同标签 2026/04/22

バージョン別の. NETサポート状況(250 7 0 7更新)

仮想マシンとテストマシンを使用して、各バージョンのオペレーティングシステムの. NETサポートをテストします。オペレーティングシステムのインストール後、対応するランタイムを測定し、スターダストエージェントをパスとして実行できます。

继续阅读