C#でCefSharpを使用してWebページを埋め込み、C#とJSのインタラクションの例を示す

C#でCefSharpを使用してWebページを埋め込み、C#とJSのインタラクションの例を示す

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

最終更新 2023/03/27 22:43
沙漠尽头的狼
読了目安 6 分
カテゴリ
.NET
タグ
.NET C# CefSharp

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

この記事では、C# WPFでCefSharpを使ってWebページを埋め込み、C#とWebページ(JS)のインタラクションを実現する簡単なサンプルを紹介します。

一、サンプル構築手順

まず、この記事のサンプルコードはこちら:WpfWithCefSharpDemo

1. プロジェクトの作成

WPFプロジェクトを作成し、例えば「WpfWithCefSharpDemo」と名付けます。Winformプロジェクトも同様です。

2. Webページの作成

埋め込む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パッケージをインストールします。Visual StudioのNuGetパッケージマネージャーで「CefSharp.Wpf」を検索してインストールしてください。

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

MainWindow.xamlCefSharp.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="以下にWebページの内容を表示"></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オブジェクトをWebページに渡す" 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ブラウザコントロールの読み込み完了後、Webページの内容を読み込む。URLまたはHTMLコンテンツを指定可能
        /// </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のWebページで呼び出しているメソッド名の先頭は小文字です。もう一度注意してください。この違いに注意が必要です。

6. 効果の表示

JSからC#のメソッドを呼び出す:黄色い枠内にWebページの内容が表示されます。HTMLボタン「C#メソッドを呼び出す」をクリックしてテストします。

C#からJSの一般メソッドを呼び出す:青い枠内にWPFコントロールが表示されます。WPFボタン「JSメソッドを呼び出す」をクリックしてテストします。

C#からJSONオブジェクトをJSに渡す:青い枠内で、WPFボタン「C#からJSONオブジェクトをWebページに渡す」をクリックしてテストします。

二、まとめ

上記のサンプルを実際にやってみてください。WPFやWinformのネイティブWebBrowserコントロールを使用したことがある方は、WPF標準のWebBrowserコントロールとCefSharpのメリット・デメリットを比較してこの記事を締めくくります(ChatGPTの回答を基にしています)。ご意見があればコメントをお寄せください。

WPF標準のWebBrowserコントロールのメリット:

  1. WebBrowserコントロールはWPFに標準搭載されており、追加のライブラリやコンポーネントをインストールする必要がありません。
  2. WebBrowserコントロールはInternet Explorerエンジンをベースにしており、Windows OSでのネイティブな互換性と安定性があります。
  3. WebBrowserコントロールは、Navigating、Navigated、LoadCompletedなど、ブラウザ関連の多くのイベントを提供しており、これらのイベントを利用してページの読み込みやナビゲーションを制御・フィードバックできます。

WPF標準のWebBrowserコントロールのデメリット:

  1. WebBrowserコントロールは古いバージョンのIEエンジンを使用しているため、最新のHTML5、CSS3などの標準をサポートしておらず、パフォーマンスもCefSharpに劣ります。
  2. WebBrowserコントロールのAPIは比較的少なく、Webナビゲーションのインターセプトやカスタムレンダリングなどの高度な機能を実装するのが難しいです。

CefSharpのメリット:

  1. CefSharpはChromiumプロジェクトをベースに構築されており、最新のHTML5、CSS3などのWeb標準をサポートし、パフォーマンスも優れています。
  2. CefSharpは豊富なAPIを提供しており、カスタムネットワークリクエスト、Webナビゲーションのインターセプト、HTMLコンテンツの変更など、さまざまな高度な機能を実装できます。
  3. CefSharpはマルチスレッドモデルとハードウェアアクセラレーションレンダリングを使用しており、UIスレッドをブロックせず、安定性とセキュリティにも優れています。

CefSharpのデメリット:

  1. CefSharpは追加のライブラリやコンポーネントのインストールが必要で、開発の複雑さが増します。
  2. 一部のシチュエーション(高密度画面でのレンダリングなど)では、CefSharpにパフォーマンスの問題が発生する可能性があります。

したがって、Webブラウザコントロールを選択する際は、具体的な要件に応じて選ぶ必要があります。単にWebページの内容を表示するだけで、高度な機能が不要であれば、WPF標準のWebBrowserコントロールで十分です。しかし、カスタムネットワークリクエストやWebナビゲーションのインターセプトなどの複雑な機能を実装する必要がある場合は、CefSharpの方が適しているでしょう。総じて、CefSharpはWPF標準のWebBrowserコントロールに比べて、より強力な機能と高いパフォーマンスを提供しますが、使用はやや複雑になります。

参考:

さらに探索

関連読書

その他の記事
同じカテゴリ / 同じタグ 2023/04/25

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

CefSharpのキャッシュ機能を適切に活用することで、アプリケーションのパフォーマンスとユーザーエクスペリエンスを向上させ、ネットワークトラフィックとサーバー負荷を削減し、オフラインアクセスをサポートするなど、非常に便利な機能です。

続きを読む
同じカテゴリ / 同じタグ 2026/04/22

各OSバージョンの.NETサポート状況(250707更新)

仮想マシンとテストマシンを使用して、各OSバージョンの.NETサポート状況を確認します。OSインストール後、対応するランタイムをインストールし、Stardustエージェントを実行できることを確認します(合格条件)。

続きを読む