zahmadsaleem / revit-webview2-demo

WebView2 Demo project for Autodesk Revit. Build UIs for Revit with your favorite web framework.
MIT License
58 stars 10 forks source link
autodesk autodesk-revit revit-api webview2

Revit WebView2 Demo

Prototype for a web interface within Autodesk Revit using WPF + WebView2.

Web apps built with any modern web frameworks can run in the setup demonstrated in this project. This example uses a web UI built with Vue.js with Vuetify. The web app is currently hosted here.

screenshot

All Revit interactions from and to the Web UI is defined in here

Contents

Installation

Current release of RevitWebView2Demo was developed with Revit 2021. It should work fine with older versions as well.

Development Setup

First things first, clone this repository

Web

Revit

How To

Change URL End Point

Change URL

Pass data between WebView and Revit

Communicate from Web UI To Revit

export function postWebView2Message({ action, payload }) {
  if (!action) {
    return;
  }
  // `window.chrome.webview` is only available in webview context
  // you can pass anything as the parameter to postMessage
  // C# will receive it as serialized json
  // { action, payload } is defined for the sake of having a standard message schema
  window.chrome?.webview?.postMessage({ action, payload });
}

C# handles the WebMessageReceived received event, when postMessage is called from javascript.

private void OnWebViewInteraction(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
    WvReceiveAction result = JsonConvert.DeserializeObject<WvReceiveAction>(e.WebMessageAsJson);
    /* do something with the action and payload received from js*/
    switch (result.action)
    {
        case "select":
            WebView2EventHandlers.HandleSelect(uidoc, e.WebMessageAsJson);
            break;
        case "create-sheet":
            App.RevitWv2Event.Raise(RevitWv2EventHandler.RevitWv2ActionsEnum.CreateSheet);
            break;
        default:
            Debug.WriteLine("action not defined");
            break;
    }
}

Communicate from C# To WebView2

ExecuteScriptAsync method of WebView2 allows to execute any javascript in the global document scope. To keep things simple and neat SendMessage method calls dispatchWebViewEvent in the DOM.

public async void SendMessage(PostMessage message)
{
    try
    {
        await Dispatcher.InvokeAsync(
            () => webView
                .ExecuteScriptAsync(
                    $"dispatchWebViewEvent({JsonConvert.SerializeObject(message)})"
                )
        );
    }
    catch (Exception e)
    {
        Debug.WriteLine(e);
    }
}

dispatchWebViewEvent handles all interactions from C# to web UI.

// function that gets called by c#
function dispatchWebViewEvent({ action, payload }) {
  if (action !== undefined) {
    document.dispatchEvent(
        new CustomEvent(action, { detail: payload })
        );
  }
};

// subscribe to custom events 
document.addEventListener(action, (e)=> /*do something with e.detail*/console.log(`event triggered, payload : ${e.detail}`))

action string is like an agreement between C# and the web UI. You define same action names on both sides.

This pattern ensures you don't have any more interaction other than just passing {action,payload}

Execute transactions from the web interface

Credits

Thanks to Petr Mitev and Ehsan Iran-Nejad for guidance and insights. Special thanks to Dimitar and Harsh for support.