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.
All Revit interactions from and to the Web UI is defined in here
- download
RevitWebView2Demo.zip
from here - extract the zip to your revit add-ins folder
- make sure the dlls are not blocked
Current release of RevitWebView2Demo
was developed with Revit 2021. It should work fine with older versions as well.
First things first, clone this repository
- Follow these instructions
- open
RevitWebView2.sln
- restore packages and relink missing dlls
- debug/build
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;
}
}
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}
- register an Event Handler that calls the transaction
- send a message from web UI
- raise event from webview2 on receiving a message from web UI
Thanks to Petr Mitev and Ehsan Iran-Nejad for guidance and insights. Special thanks to Dimitar and Harsh for support.