2011-05-10 17 views
13

Mi chiedevo se è possibile ottenere la posizione assoluta dell'elemento HTML specifico che ho caricato nel controllo webbrowser con C#.ottenendo la posizione assoluta dell'elemento HTML nel controllo webbrowser con C#

Ho provato quasi tutte le opzioni che .Net fornisce .. nessuno di loro mi dà la posizione corretta. tutti mi danno 0 per coordinata Y .. l'elemento è sicuramente non è in 0 ..

qualcuno ha qualche soluzione o idea per risolvere questo?

+0

cosa stai cercando di realizzare? Sarà molto più facile fornire una risposta una volta che il problema reale emergerà. – agradl

+0

voglio prendere screenshot per elemento specifico .. Ho bisogno di scorrere fino all'elemento specificato quindi impostare la larghezza + altezza del controllo webbrowser simile a quell'elemento .. e infine prendere screenshot per quell'elemento .. – SolidSnake

risposta

11

Ecco la soluzione ho ottenuto finora:

// impostare la dimensione del nostro browser web per essere la stessa dimensione come la larghezza int immagine , altezza; width = webBrowser1.Document.Images [0] .ClientRectangle.Width; height = webBrowser1.Document.Images [0] .ClientRectangle.Height;

webBrowser1.Width = width; 
webBrowser1.Height = height; 

//scroll vertically to that element 
webBrowser1.Document.Images[0].OffsetParent.ScrollIntoView(true); 

//calculate x, y offset of the element 
int x = webBrowser1.Document.Images[s].OffsetRectangle.Left + 
webBrowser1.Document.Images[s].OffsetParent.OffsetRectangle.Left + 
webBrowser1.Document.Images[s].OffsetParent.OffsetParent.OffsetRectangle.Left+ 
webBrowser1.Document.Images[s].OffsetParent.OffsetParent.OffsetParent.OffsetRectangle.Left+ 
webBrowser1.Document.Images[s].OffsetParent.OffsetParent.OffsetParent.OffsetParent.OffsetRectangle.Left; 

int y = webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollTop; 

//now scroll to that element 
webBrowser1.Document.Window.ScrollTo(x, y); 

ora questo codice funziona perfettamente .. ma c'è un problema con il calcolo delle compensazioni. Ho bisogno di calcolare l'offset dell'elemento, quindi calcolare l'offset del componente offset, ecc. Devo farlo dinamicamente senza aggiungerlo uno alla volta. Non so come farlo. qualche idea?

EDIT: ecco la mia ultima e definitiva versione e funziona con qualsiasi elemento HTML troverà la posizione assoluta di qualsiasi elemento che voglio ..

public int getXoffset(HtmlElement el) 
    { 
     //get element pos 
     int xPos = el.OffsetRectangle.Left; 

     //get the parents pos 
     HtmlElement tempEl = el.OffsetParent; 
     while (tempEl != null) 
     { 
      xPos += tempEl.OffsetRectangle.Left; 
      tempEl = tempEl.OffsetParent; 
     } 

     return xPos; 
    } 

    public int getYoffset(HtmlElement el) 
    { 
     //get element pos 
     int yPos = el.OffsetRectangle.Top; 

     //get the parents pos 
     HtmlElement tempEl = el.OffsetParent; 
     while (tempEl != null) 
     { 
      yPos += tempEl.OffsetRectangle.Top; 
      tempEl = tempEl.OffsetParent; 
     } 

     return yPos; 
    } 

quindi utilizzare la posizione con:

//now scroll to that element 
webBrowser1.Document.Window.ScrollTo(x, y); 

terminato!

3

Grazie, funziona come un fascino. Ho dovuto riscriverlo come VB, e voglio solo condividere la soluzione:

Function GetXOffSet(ByVal elem As HtmlElement) As Integer 
    Dim xPos As Integer = elem.OffsetRectangle.Left 
    Dim tElm As HtmlElement = elem.OffsetParent 
    Dim trig As Boolean = False 
    While Not trig 
     Try 
      xPos += tElm.OffsetRectangle.Left 
      tElm = tElm.OffsetParent 
     Catch ex As Exception 
      trig = True 
     End Try 
    End While 
    Return xPos 
End Function 

Function GetYOffSet(ByVal elem As HtmlElement) As Integer 
    Dim yPos As Integer = elem.OffsetRectangle.Top 
    Dim tElm As HtmlElement = elem.OffsetParent 
    Dim trig As Boolean = False 
    While Not trig 
     Try 
      yPos += tElm.OffsetRectangle.Top 
      tElm = tElm.OffsetParent 
     Catch ex As Exception 
      trig = True 
     End Try 
    End While 
    Return yPos 
End Function 
4

mi piace risposte precedenti, ma scorrendo genitore oggetti due volte non è molto efficace. Ricorda: stai lavorando con COM/ActiveX qui. Questo funziona molto più veloce:

public Point GetOffset(HtmlElement el) 
{ 
    //get element pos 
    Point pos = new Point(el.OffsetRectangle.Left, el.OffsetRectangle.Top); 

    //get the parents pos 
    HtmlElement tempEl = el.OffsetParent; 
    while (tempEl != null) 
    { 
     pos.X += tempEl.OffsetRectangle.Left; 
     pos.Y += tempEl.OffsetRectangle.Top; 
     tempEl = tempEl.OffsetParent; 
    } 

    return pos; 
} 

e poi

var point = GetOffset(element); 
var x = point.X; 
var y = point.Y; 
1

Proprio la condivisione di un'implementazione leggermente diversa in base alle mie esigenze per ottenere il posizionamento retangle assoluto:

public Rectangle GetAbsoluteRectangle(HtmlElement element) { 
    //get initial rectangle 
    Rectangle rect = element.OffsetRectangle; 

    //update with all parents' positions 
    HtmlElement currParent = element.OffsetParent; 
    while (currParent != null) { 
      rect.Offset(currParent.OffsetRectangle.Left, currParent.OffsetRectangle.Top); 
      currParent = currParent.OffsetParent; 
    } 

    return rect; 
} 
0

Non so perché, ma offsetParent non è sempre restituito (caso di IE11, oggetto mappa) Ho dovuto aggiungere parentElement nel ciclo quando parentOffset non è fornito

While parent IsNot Nothing 
      y += parent.offsetTop 
      x += parent.offsetLeft 
      If parent.offsetParent IsNot Nothing Then 
       parent = parent.offsetParent 
      Else 
       parent = parent.parentElement 
      End If 
    End While 

E è necessario aggiungere la posizione del browser IE, lo spazio menu e confini ...

2

C'è un modo diretto per ottenere le coordinate.IHTMLElement2 ha il metodo getBoundingClientRect che ti fornisce le coordinate dell'elemento.

IHTMLDocument3 doc = (IHTMLDocument3)this.webbrowser.Document; 
IHTMLElement2 element = (IHTMLElement2)doc.getElementById(idElement); 
IHTMLRect rect = element.getBoundingClientRect(); 

int x = rect.left; 
int y= rect.top; 
0

Il modo più pulito che funziona per me è la seguente:

HtmlElement elem = webBrowser.Document.GetElementById(idElement); IHTMLRect rect = ((IHTMLElement2) elem.DomElement).getBoundingClientRect(); // rect.top and rect.left represent absolute coordinates.

Problemi correlati