2010-08-12 20 views
14

Considero que es una solicitud bastante simple, pero parece que no puedo encontrar una respuesta concluyente en mis búsquedas. ¿Cómo puedo determinar los límites de un elemento visual en particular en mi ventana, en relación con algún otro elemento principal?Determine el límite de un elemento WPF relativo a algún elemento primario

He intentado usar LayoutInformation.GetLayoutSlot pero esto parece devolver un Rect a 0,0 y no refleja la ubicación real del elemento.

Lo que intento hacer es tomar una "captura de pantalla" de una ventana usando RenderTargetBitmap y luego recortarla en un elemento particular, pero no puedo obtener los límites del elemento para saber a qué cortar el mapa de bits.

Respuesta

15

Es bastante simple:

public static Rect BoundsRelativeTo(this FrameworkElement element, 
             Visual relativeTo) 
{ 
    return 
    element.TransformToVisual(relativeTo) 
      .TransformBounds(LayoutInformation.GetLayoutSlot(element)); 
} 

De hecho, puede ser excesiva para ponerlo en un método separado.

+3

'GetLayoutSlot' obtiene el espacio asignado en el diseño para el elemento, pero el tamaño del elemento real podría ser diferente si tiene un ancho/alto explícito y/o una transformación. Para obtener el rect de tamaño "verdadero", prueba con 'element.RenderTransform.TransformBounds (new Rect (element.RenderSize))'. – nmclean

3

No importa, que finalmente logró averiguarlo utilizando una combinación de LayoutInformation.GetLayoutSlot() (aunque probablemente podría haber utilizado ya sea ActualWidth/o ActualHeightRenderSize) y UIElement.TranslatePoint().

Parece una solución bastante complicado cuando podría ser tan simple como esto:

myElement.GetBounds(relativeElement); 

Oh, bueno. Tal vez sea hora de un método de extensión. :)

+1

No hay método GetBounds en FrameworkElement. – ygoe

+1

Estaba diciendo que debería haberlo. – devios1

+1

¿Podría mostrar la solución completa? No lo hice funcionar. Siempre fue incorrecto en relación con algún elemento principal. Por ahora, estoy convirtiendo todo en coordenadas de pantalla con 'myElement.PointToScreen (new Point())' que está bien para manejar WM_NCHITTEST. Pero todavía lo considero un hack. – ygoe

3

La opción LayoutSlot no funcionó para mí en absoluto. Esto terminó dándome una posición de niño respecto a un control/ancestro principal especificada:

public static Rect BoundsRelativeTo(this FrameworkElement child, Visual parent) 
    { 
     GeneralTransform gt = child.TransformToAncestor(parent); 
     return gt.TransformBounds(new Rect(0, 0, child.ActualWidth, child.ActualHeight)); 
    } 
+0

Esto funcionó para mí, la respuesta aceptada no. Trabajar con un borde en una cuadrícula con WPF en .NET Framework 4.5.2. – pauldendulk

0

Teniendo en cuenta algunas sugerencias que encontré aquí esta resuelto el problema para mí.

item.TransformToVisual(relativeToElement) 
    .TransformBounds(new Rect(item.RenderSize)); 
Cuestiones relacionadas