webview_celldouble

承知いたしました。**イベントリスナーを挿入する方法**での実装コードをもう一度ご提供いたします。以下に、必要なC#コードとJavaScriptコードをまとめ、各部分の説明を付け加えています。

---

## **全体の流れ**

1. **WebView2の初期化と設定**:
   - Webメッセージの受信を有効化。
   - ページのナビゲーション完了後にJavaScriptを挿入。

2. **JavaScriptコードの挿入**:
   - ページ内のすべての`<td>`要素のダブルクリックイベントを監視するスクリプトを挿入。

3. **C#側でメッセージを受信し、データグリッドビューを更新**:
   - JavaScriptから送信されたデータを受信し、データグリッドビューに反映。

---

## **1. WebView2の初期化と設定**

### **手順**

- フォームに`WebView2`コントロールと`DataGridView`コントロールを配置します。
  - `WebView2`コントロールの名前:`webView`
  - `DataGridView`コントロールの名前:`dataGridView`

- **WebView2の初期化コード**を記述します。

### **コード**

```csharp
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        InitializeWebView2();
    }

    private async void InitializeWebView2()
    {
        // WebView2を初期化
        await webView.EnsureCoreWebView2Async(null);

        // Webメッセージの受信を有効化
        webView.CoreWebView2.Settings.IsWebMessageEnabled = true;

        // ページのナビゲーションが完了したときにJavaScriptを挿入
        webView.NavigationCompleted += WebView_NavigationCompleted;

        // Webメッセージ受信イベントを設定
        webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;

        // ローカルのHTMLファイルを表示(パスを適切に設定してください)
        webView.Source = new Uri("file:///C:/path/to/your/local/file.html");
    }
}
```

**ポイント**:

- **`IsWebMessageEnabled`を`true`に設定**:JavaScriptからC#へのメッセージ送信を有効にします。
- **`NavigationCompleted`イベント**:ページの読み込みが完了したタイミングでJavaScriptを挿入します。
- **`WebMessageReceived`イベント**:JavaScriptからのメッセージを受信します。

---

## **2. JavaScriptコードの挿入**

### **手順**

- **`NavigationCompleted`イベントハンドラ**内で、JavaScriptコードをページに挿入します。

### **コード**

```csharp
private async void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
    await InjectJavaScript();
}

private async Task InjectJavaScript()
{
    string script = @"
        (function() {
            document.addEventListener('dblclick', function(event) {
                var target = event.target;
                if (target && target.nodeName === 'TD') {
                    var cellValue = target.innerText;
                    var rowIndex = target.parentNode.rowIndex;
                    var cellIndex = target.cellIndex;
                    window.chrome.webview.postMessage(JSON.stringify({
                        value: cellValue,
                        rowIndex: rowIndex,
                        cellIndex: cellIndex
                    }));
                }
            });
        })();
    ";
    await webView.ExecuteScriptAsync(script);
}
```

**説明**:

- **即時関数でスクリプトを囲む**:グローバルスコープへの影響を避けます。
- **`document.addEventListener('dblclick', ...)`**:ページ全体でダブルクリックイベントを監視します。
- **ターゲットが`<td>`要素の場合に処理を実行**。
- **セルの値と位置を取得し、JSON形式でC#側に送信**。

---

## **3. C#側でメッセージを受信し、データグリッドビューを更新**

### **手順**

- **`WebMessageReceived`イベントハンドラ**で、JavaScriptから送信されたデータを受信します。
- **受信したデータを解析し、データグリッドビューを更新**します。

### **コード**

```csharp
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
    // メッセージをJSONとして取得
    string json = e.WebMessageAsJson;

    // JSONを解析してデータを取得
    dynamic data = JsonConvert.DeserializeObject(json);

    string cellValue = data.value;
    int rowIndex = data.rowIndex;
    int cellIndex = data.cellIndex;

    // データグリッドビューを更新
    UpdateDataGridView(cellValue, rowIndex, cellIndex);
}

private void UpdateDataGridView(string cellValue, int rowIndex, int cellIndex)
{
    // UIスレッドで実行
    Invoke(new Action(() =>
    {
        // 行の追加が必要な場合
        while (dataGridView.Rows.Count <= rowIndex)
        {
            dataGridView.Rows.Add();
        }
        // 列の追加が必要な場合
        while (dataGridView.Columns.Count <= cellIndex)
        {
            dataGridView.Columns.Add($"Column{cellIndex}", $"Column{cellIndex}");
        }

        // セルに値を設定
        dataGridView.Rows[rowIndex].Cells[cellIndex].Value = cellValue;
    }));
}
```

**ポイント**:

- **`JsonConvert.DeserializeObject`を使用**:JSON形式のデータを解析します。
- **`Invoke`を使用**:データグリッドビューの更新はUIスレッドで行う必要があります。
- **行と列の追加**:セルの位置に対応するように、必要に応じて行と列を追加します。

---

## **完全なコード例**

```csharp
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        InitializeWebView2();
    }

    private async void InitializeWebView2()
    {
        await webView.EnsureCoreWebView2Async(null);
        webView.CoreWebView2.Settings.IsWebMessageEnabled = true;

        webView.NavigationCompleted += WebView_NavigationCompleted;
        webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;

        // ローカルのHTMLファイルを表示(パスを適切に設定してください)
        webView.Source = new Uri("file:///C:/path/to/your/local/file.html");
    }

    private async void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
    {
        await InjectJavaScript();
    }

    private async Task InjectJavaScript()
    {
        string script = @"
            (function() {
                document.addEventListener('dblclick', function(event) {
                    var target = event.target;
                    if (target && target.nodeName === 'TD') {
                        var cellValue = target.innerText;
                        var rowIndex = target.parentNode.rowIndex;
                        var cellIndex = target.cellIndex;
                        window.chrome.webview.postMessage(JSON.stringify({
                            value: cellValue,
                            rowIndex: rowIndex,
                            cellIndex: cellIndex
                        }));
                    }
                });
            })();
        ";
        await webView.ExecuteScriptAsync(script);
    }

    private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
    {
        string json = e.WebMessageAsJson;
        dynamic data = JsonConvert.DeserializeObject(json);

        string cellValue = data.value;
        int rowIndex = data.rowIndex;
        int cellIndex = data.cellIndex;

        UpdateDataGridView(cellValue, rowIndex, cellIndex);
    }

    private void UpdateDataGridView(string cellValue, int rowIndex, int cellIndex)
    {
        Invoke(new Action(() =>
        {
            while (dataGridView.Rows.Count <= rowIndex)
            {
                dataGridView.Rows.Add();
            }
            while (dataGridView.Columns.Count <= cellIndex)
            {
                dataGridView.Columns.Add($"Column{cellIndex}", $"Column{cellIndex}");
            }
            dataGridView.Rows[rowIndex].Cells[cellIndex].Value = cellValue;
        }));
    }
}
```

---

## **補足説明**

### **1. 必要なパッケージの追加**

- **`Newtonsoft.Json`ライブラリ**を使用しています。NuGetパッケージマネージャーから追加してください。

  ```bash
  Install-Package Newtonsoft.Json
  ```

### **2. フォームのデザイン**

- **`WebView2`コントロール**と**`DataGridView`コントロール**をフォームに配置します。
  - 適切な大きさと位置に配置してください。

### **3. ローカルHTMLファイルのパス**

- **`webView.Source`**に指定するHTMLファイルのパスを正しく設定してください。
  - 例:`webView.Source = new Uri("file:///C:/Users/YourUser/Documents/sample.html");`

### **4. セキュリティに関する注意**

- **`IsWebMessageEnabled`を`true`に設定**することで、JavaScriptからC#へのメッセージ送信が可能になります。
- **信頼できないコンテンツを表示する場合**は、セキュリティリスクとなる可能性があるため、適切な対策を講じてください。

### **5. エラーハンドリング**

- **例外処理**を適切に追加して、エラーが発生した場合の対策を行ってください。

### **6. データグリッドビューの列の設定**

- 自動的に列を追加していますが、必要に応じて列の設定や名前をカスタマイズしてください。

---

## **動作確認**

- **アプリケーションを実行**し、WebView2に表示されたHTML内のテーブルセルをダブルクリックしてください。
- **データグリッドビュー**に、ダブルクリックしたセルの値が反映されます。

---

## **まとめ**

- **HTMLファイルを変更せず**に、C#側からJavaScriptを挿入することで、テーブルセルのダブルクリックイベントを検出しました。
- **取得したセルの値と位置情報**をC#側に送信し、データグリッドビューに反映させています。
- **不特定多数のテーブル**に対応しており、テーブルのIDやクラスに依存していません。

---

ご不明な点や追加のご質問がありましたら、お気軽にお知らせください。実装がうまく進むことを願っております。

いいなと思ったら応援しよう!