2011-05-10 17 views
13

Me preguntaba si es posible obtener la posición absoluta del elemento HTML específico que he cargado en el control del webbrowser con C#.obteniendo la posición absoluta del elemento HTML en el control del webbrowser con C#

Probé casi todas las opciones que .Net proporciona .. ninguno de ellos me da la posición correcta. todos me dan 0 para la coordenada Y ... el elemento definitivamente no está en 0 ..

¿Alguien tiene alguna solución o idea para resolver esto?

+0

lo que estás tratando de lograr? Será mucho más fácil dar una respuesta una vez que surja el problema real. – agradl

+0

Quiero tomar una captura de pantalla para un elemento específico. Necesito desplazarme al elemento especificado, establecer el ancho + alto del control del navegador web similar a ese elemento ... y finalmente tomar una captura de pantalla de ese elemento. – SolidSnake

Respuesta

11

aquí es la solución que tengo hasta ahora:

// establece el tamaño de nuestro navegador web que sea del mismo tamaño que el ancho de la imagen int , altura; 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); 

ahora este código funciona perfectamente .. pero hay un problema con el cálculo de las compensaciones. Necesito calcular el offsetparent del elemento y luego calcular el offsetparent del offsetparent, etc. Necesito hacer eso dinámicamente sin agregarlo uno por uno ... No sé cómo hacer eso. ¿algunas ideas?

EDIT: aquí es mi última y definitiva versión y funciona con cualquier elemento HTML que se encuentra la posición absoluta de cualquier elemento que quiero ..

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; 
    } 

a continuación, utilizar la posición con:

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

done!

3

Gracias, funciona como un encanto. Tenía que volver a escribir como VB, y sólo quiero compartir la solución:

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

me gustan las respuestas anteriores, pero la iteración a través padre se opone dos veces no es muy eficaz. Recuerde: está trabajando con COM/ActiveX aquí. Esto funciona mucho más rápido:

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; 
} 

y luego

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

Sólo compartir una implementación ligeramente diferente en función de mis necesidades para conseguir la absoluta retangle posicionamiento:

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
No

sé por qué pero offsetParent no siempre se devuelve (caso de IE11, objeto de mapa) Tuve que agregar parentElement en el ciclo cuando parentOffset no se proporciona

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 

Y es necesario agregar posición navegador Internet Explorer, el espacio de menú y las fronteras ...

2

No es una forma directa de obtener las coordenadas.IHTMLElement2 tiene el método getBoundingClientRect que le proporciona las coordenadas del 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

La manera más limpia que funciona para mí es la siguiente:

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

Cuestiones relacionadas