söndag 8 juli 2007

WebBrowser-kontrollen i .NET 2.0

Jag tänkte att jag skulle dela med mig av några erfarenheter från mitt senaste miniprojekt som involverade WebBrowser-kontrollen i .NET 2.0. Ett par observationer som kan underlätta för andra som tänker använda kontrollen (eftersom dokumentationen på nätet inte är sådär otroligt utförlig):
  • Eventet DocumentCompleted uppstår varje gång ett dokument är färdigladdat och renderat, vilket innebär att det triggas lika många gånger som det finns frames (eller iframes) på sidan. Om man har kod i eventhanteraren som ska manipulera eller tolka innehållet i det laddade dokumentet är det därför viktigt att man håller koll på vilket dokument det är man tar emot. Detta gör man enklast via WebBrowserDocumentCompletedEventArgs.Url.
  • I .NET 2.0 krävs FullTrust-permissionset:et för att ett program ska få använda en WebBrowser-kontroll. Vad jag förstår så har detta justerats i 3.0 genom introducerandet av System.Security.Permissions.WebBrowserPermission, vilket naturligtvis är mycket bättre eftersom det då går att tagga ned lite på rättigheterna för programmet i övrigt.
  • När man ska undersöka DOM-trädet eller HTML-koden för ett laddat dokument som innehåller frames/iframes så är det inte alltid som de element man söker efter finns med, även om de syns i browserfönstret. Jag tror att detta har att göra med hur IE (för det är dess motor som används) uppdaterar DOM-trädet för dynamiskt innehåll, eller något liknande. Däremot, om man vet vilken frame som de eftersökta elementen finns i så kan man leta sig fram till dem genom browser.Document.Window.Frames[frameIndex].Document. Detta HtmlDocument har metoder som exempelvis GetElementById som funkar, under förutsättning att det aktuella frame-dokumentet är laddat fullständigt. (Här har jag antagit att instansen av WebBrowser-kontrollen heter browser och att index för den intressanta framen är lagrat i frameIndex. Jag misstänker dock att förpopulerade samlingar som HmtlDocument.Links och liknande inte uppdateras korrekt för de olika frame-dokumenten. Vet inte varför, och jag kan inte med hundra procents säkerhet säga att det är på det sättet, men jag stötte på det ett par gånger i alla fall (varför jag använde HtmlDocument.GetElementsByTagName istället).
  • När du navigerar med din WebBrowser så laddas dokumenten asynkront, vilket är bra - det vore ju tråkigt om programmet slutade svara bara för att en webbsida tog lång tid på sig att ladda.
  • Om du behöver fylla i formulärfält, klicka på knappar eller på något annat sätt härma en verklig användares handlingar så kan du manipulera DOM-trädet precis som du skulle gjort med Javascript. Metoden HtmlElement.InvokeMember används för att trigga events på element i dokumentet (exempelvis "click" på knappar/länkar).
Hoppas det hjälper!

2 kommentarer:

  1. Känns lite tråkigt att jag inte har något konto att prova din lilla uppfinning på. Verkar iaf som att den har blivit lite mer sofistikerad sedan jag testade den komponenten för ca 2 år sedan (Jäsiken vad tiden går). Kommer de gamla inläggen att hamna här snart eller vad är planen? Arkivera?

    SvaraRadera
  2. Hm jag läste igenom några av dem igår kväll och jag kan väl säga så mycket som att de inte kommer läggas upp här. De har dock ett tillräckligt högt nostalgiskt värde för att slutförvaras på någon säker plats som != Lunarstorm.

    SvaraRadera