2010-08-12 10 views
14

Considero questa una richiesta piuttosto semplice, ma non riesco a trovare una risposta definitiva nelle mie ricerche. Come posso determinare i limiti di un particolare elemento visivo nella mia finestra, rispetto a qualche altro elemento genitore?Determina il rect di delimitazione di un elemento WPF relativo a un genitore

Ho provato con LayoutInformation.GetLayoutSlot ma questo sembra solo per restituire un Rect a 0,0 e non riflette la posizione attuale dell'elemento.

Quello che sto cercando di fare è prendere uno "screenshot" di una finestra usando RenderTargetBitmap e poi ritagliarlo su un elemento particolare, ma non riesco a ottenere i limiti dell'elemento per sapere su cosa ritagliare la bitmap!

risposta

15

E 'molto semplice:

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

In effetti può essere eccessivo per dirla in un metodo separato.

+3

'GetLayoutSlot' ottiene lo spazio allocato nel layout per l'elemento, ma la dimensione effettiva dell'elemento potrebbe essere diversa se ha una larghezza/altezza esplicita e/o una trasformazione. Per ottenere la dimensione "vera", prova 'element.RenderTransform.TransformBounds (new Rect (element.RenderSize))'. – nmclean

3

Nevermind, ho finalmente riuscito a capirlo utilizzando una combinazione di LayoutInformation.GetLayoutSlot() (anche se probabilmente potuto usare sia ActualWidth/ActualHeight o RenderSize) e UIElement.TranslatePoint().

Sembra una soluzione piuttosto complicata quando potrebbe essere semplice come questo:

myElement.GetBounds(relativeElement); 

Oh bene. Forse il tempo per un metodo di estensione. :)

+1

Non esiste un metodo GetBounds in FrameworkElement. – ygoe

+1

Stavo dicendo che dovrebbe esserci. – devios1

+1

Mostreresti per favore la soluzione completa? Non l'ho fatto funzionare. Era sempre sbagliato rispetto ad un elemento genitore. Per ora, sto convertendo tutto in coordinate dello schermo con 'myElement.PointToScreen (new Point())' che va bene per gestire WM_NCHITTEST. Ma lo considero ancora un hack. – ygoe

3

L'opzione LayoutSlot non ha funzionato affatto per me. Questo ha finito per avermi dato una posizione bambino rispetto ad un controllo/antenato padre specificato:

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

Questo ha funzionato per me, la risposta accettata no. Lavorare con un bordo in una griglia con WPF in .NET Framework 4.5.2. – pauldendulk

0

Tenendo conto di alcuni suggerimenti che ho trovato qui ha risolto il problema per me.

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