Todos os posts
Inteligência Artificial

WebView2 no WinForms: UI em HTML dentro de app desktop

WebView2 WinForms é a combinação que uso no WS-engine pra ter um painel desktop com cara moderna sem me enfiar numa curva íngreme de WPF. É um controle oficial da Microsoft que embute um Chromium dentro de um Form clássico — o resultado é que a interface da aplicação é HTML, CSS e JavaScript locais,

6 min de leitura 2 views
WebView2 no WinForms: UI em HTML dentro de app desktop

WebView2 WinForms é a combinação que uso no WS-engine pra ter um painel desktop com cara moderna sem me enfiar numa curva íngreme de WPF. É um controle oficial da Microsoft que embute um Chromium dentro de um Form clássico — o resultado é que a interface da aplicação é HTML, CSS e JavaScript locais, e o backend em C# conversa com o painel por mensagens JSON. Este artigo mostra o código real dessa integração, decisões de arquitetura e os cuidados que descobri na prática. Pra contexto maior, o guia de engenharia reversa com IA.

Por que WebView2 e não WPF puro

Primeira tentativa foi WPF nativo. Travei na segunda tela — DataGrid com estilo decente exige conhecimento específico, animações precisam de storyboard, binding de dados tem armadilhas sutis com threads. Boa escolha pra quem já domina a stack, mas eu não dominava. Horas de leitura pra fazer uma barra de progresso ter transição suave que, em CSS, seriam duas linhas.

WebView2 WinForms resolve o problema trocando a curva. Em vez de aprender WPF do zero, reaproveito conhecimento web que já tenho — flexbox, grid, variáveis CSS, event listeners em JS. O custo é embarcar o runtime do Chromium, mas no Windows 10 recente e no Windows 11 ele já vem instalado como componente do sistema. Pra projeto pessoal com UI que precisa iterar rápido, foi a decisão certa.

Instalar o controle via NuGet Microsoft.Web.WebView2

O controle vem do pacote NuGet Microsoft.Web.WebView2. Adicionei via Visual Studio, mas também funciona por linha de comando com nuget install. O pacote traz dois namespaces principais: Microsoft.Web.WebView2.Core (contratos e eventos de baixo nível) e Microsoft.Web.WebView2.WinForms (o controle visual).

Além do pacote, o usuário final precisa do Edge WebView2 Runtime instalado no sistema. No Windows 11 e no Windows 10 recente ele vem junto; em instalações mais antigas, pode faltar. O código precisa prever isso graciosamente — captura exceção específica e orienta o usuário a instalar.

Hospedar o controle no WinForms com Dock Fill

Dentro do Form principal, instancio o controle com new WebView2 { Dock = DockStyle.Fill } e adiciono como filho de um painel. Dock Fill garante que o WebView ocupa todo o espaço disponível do container e redimensiona junto com a janela. Pra separar o painel HTML de controles clássicos do Form (barra de menu, status bar), uso um Panel container e deixo o Dock do WebView dentro dele.

Essa separação importa quando quero misturar controles nativos com HTML. Por exemplo, menu principal em WinForms (ganha de graça o estilo nativo do Windows) e corpo em WebView2 (ganha a estética custom). O controle do WebView2 WinForms coexiste com qualquer outro controle do Form sem fricção.

EnsureCoreWebView2Async e tratar runtime ausente

Inicializar o controle não é síncrono. Precisa chamar EnsureCoreWebView2Async(null) e aguardar — essa chamada baixa configuração do runtime, prepara o ambiente de execução e emite erros se faltar algo. O argumento null usa o environment padrão (adequado pra 99% dos casos).

Importante: a chamada pode lançar WebView2RuntimeNotFoundException quando o runtime não está instalado. No WS-engine, capturo essa exceção específica e mostro um MessageBox com link direto pra página de download do runtime. Sem esse tratamento, o app abre, tenta inicializar e falha silenciosamente — usuário leigo não entende por que a janela ficou em branco.

Carregar HTML local via URI absoluta file://

O painel não é servido por servidor HTTP local. É um arquivo index.html no disco, dentro da pasta assets/webview/ do executável. Pra navegar pra ele, construo uma URI absoluta no formato file:// e chamo CoreWebView2.Navigate(new Uri(_htmlPath).AbsoluteUri). O new Uri(path).AbsoluteUri cuida da codificação (espaços, caracteres especiais) sem eu precisar lembrar das regras.

Esse padrão de servir HTML do disco local tem vantagem clara pra apps desktop: zero latência, zero dependência de rede, zero porta de servidor a configurar. O JS do painel pode fazer fetch pra APIs externas se precisar, mas o esqueleto da interface é um arquivo estático lido do disco. Mantenho os assets em index.html + app.js + style.css, três arquivos sem build step — editei direto, recarreguei a janela, vi o resultado.

IPC: PostWebMessageAsJson (C#→JS) e WebMessageReceived (JS→C#)

A ponte entre o backend em C# e o JS do painel funciona por mensagens JSON em ambas as direções. Do C# pro JS, chamo _webView.CoreWebView2.PostWebMessageAsJson(json). Do JS pro C#, uso window.chrome.webview.postMessage(obj) e, no C#, assino CoreWebView2.WebMessageReceived.

No WS-engine, defini duas shapes de mensagem. Backend pro UI usa { type: "leaderboard"|"timer"|"status"|"capture", ... payload }. UI pro backend usa { cmd: "toggle"|"reset"|"save"|"filter"|"ready", args: {...} }. O "ready" é o primeiro — o JS avisa o backend quando terminou de carregar e está pronto pra receber dados. Até esse ping chegar, o backend não começa a empurrar snapshots.

Parser JSON do lado do C# pode ser qualquer coisa — Newtonsoft.Json, System.Text.Json. Pra evitar dependência adicional no projeto do WebView2 WinForms, usei Regex simples pra extrair os campos que me interessavam. Vale pra mensagens pequenas e previsíveis; projetos maiores usariam um parser real sem pensar duas vezes.

Vantagens práticas: iterar sem recompilar o .exe

O ganho que mais me surpreendeu: iterar o painel sem recompilar o executável. Como os arquivos HTML/CSS/JS são lidos do disco a cada carga, posso editar app.js ou style.css no editor, fechar e reabrir a janela principal, e ver o novo visual — sem passar pelo compilador C#. Em sessões de ajuste visual, isso acelera muito.

Pra uso em produção, embarquei os arquivos na pasta do executável e eles seguem como assets normais na distribuição. O usuário final não vê diferença entre interface compilada e interface servida por disco; o que ele vê é um painel que abre junto com o programa. Dentro da pasta de distribuição, uma subpasta assets/webview guarda o index.html, o app.js, o style.css e qualquer ícone usado no painel. Zero build step, zero bundle, zero minificação — se o painel ficar grande demais, dá pra adicionar um step de build depois sem mudar o fluxo de carregamento no C#.

O conjunto WebView2 WinForms + HTML local é o atalho mais pragmático que achei pra desktop no Windows com cara moderna. Troca a complexidade de WPF pela complexidade de embarcar um Chromium que o Windows atual já tem instalado — pra mim, troca válida e repetível em outros projetos pequenos. Pra ver essa combinação em um projeto completo, dá uma volta no ModoDev.

Avalie este artigo

0.0 · 0 avaliações

Continue lendo

Comentários

Carregando comentários...

Deixe seu comentário