2013-08-21 11 views
5

Mam kontrolkę WebBrowser w WinForm, której właściwość URL jest ustawiona na zewnętrzną stronę internetową. Mam również obsługę zdarzeń dla zdarzenia DocumentCompleted. Wewnątrz tego programu obsługi próbuję uzyskać określone elementy, ale wb.Document.Body wydaje się przechwytywać kod HTML przed wykonaniem polecenia onload.Uzyskiwanie zawartości treści HTML w WinForms WebBrowser po zdarzeniu onload body wykonuje się

{System.Windows.Forms.HtmlElement} 
    All: {System.Windows.Forms.HtmlElementCollection} 
    CanHaveChildren: true 
    Children: {System.Windows.Forms.HtmlElementCollection} 
    ClientRectangle: {X = 0 Y = 0 Width = 1200 Height = 0} 
    Document: {System.Windows.Forms.HtmlDocument} 
    DomElement: {mshtml.HTMLBodyClass} 
    ElementShim: {System.Windows.Forms.HtmlElement.HtmlElementShim} 
    Enabled: true 
    FirstChild: null 
    htmlElement: {mshtml.HTMLBodyClass} 
    Id: null 
    InnerHtml: "\n" 
    InnerText: null 
    Name: "" 
    NativeHtmlElement: {mshtml.HTMLBodyClass} 
    NextSibling: null 
    OffsetParent: null 
    OffsetRectangle: {X = 0 Y = 0 Width = 1200 Height = 0} 
    OuterHtml: "<body onload=\"evt_Login_onload(event);\" uitheme=\"Web\">\n</body>" 
    OuterText: null 
    Parent: {System.Windows.Forms.HtmlElement} 
    ScrollLeft: 0 
    ScrollRectangle: {X = 0 Y = 0 Width = 1200 Height = 0} 
    ScrollTop: 0 
    shimManager: {System.Windows.Forms.HtmlShimManager} 
    ShimManager: {System.Windows.Forms.HtmlShimManager} 
    Style: null 
    TabIndex: 0 
    TagName: "BODY" 

"<body onload=\"evt_Login_onload(event);\" uitheme=\"Web\">\n</body>" to treść przed JavaScript. Czy istnieje sposób przechwytywania stanu znacznika body po wykonaniu evt_Login_onload(event);?

Próbowałem również przy użyciu wb.Document.GetElementById("id"), ale zwraca null.

Odpowiedz

6

Oto jak można to zrobić, mam umieścić niektóre komentarze inline:

private void Form1_Load(object sender, EventArgs e) 
{ 
    bool complete = false; 
    this.webBrowser1.DocumentCompleted += delegate 
    { 
     if (complete) 
      return; 
     complete = true; 
     // DocumentCompleted is fired before window.onload and body.onload 
     this.webBrowser1.Document.Window.AttachEventHandler("onload", delegate 
     { 
      // Defer this to make sure all possible onload event handlers got fired 
      System.Threading.SynchronizationContext.Current.Post(delegate 
      { 
       // try webBrowser1.Document.GetElementById("id") here 
       MessageBox.Show("window.onload was fired, can access DOM!"); 
      }, null); 
     }); 
    }; 

    this.webBrowser1.Navigate("http://www.example.com"); 
} 
+1

+1 mogę potwierdzić tę odpowiedź pracował dla mnie, chociaż nie miałem potrzeby korzystania 'SyncronizationContext.Current.Post() 'ponieważ używam pojedynczego wątku. –

+0

@StevendeSalas, celem 'SyncronizationContext.Current.Post' było zwrócenie z obsługi zdarzenia' onload' i kontynuowanie asynchronicznego działania w tym samym wątku UI (więc ewentualne wyjątki nie byłyby zgłaszane w kodzie MSHTML wystrzeliwującym zdarzenie). Od tego czasu kod ewoluował nieco, aby zamiast tego użyć 'async' /' await', [example] (http://stackoverflow.com/a/19063643/1768303). – Noseratio

+0

Próbowałem podobne podejście, ale nie działa. Czy możesz spojrzeć na http://stackoverflow.com/questions/22697987/form-become-blank-intermittently? – Lijo

Powiązane problemy