2012-05-04 22 views
6

Ho un elemento DrawingVisual che rappresents un percorso che la geometria è descritto da questo syntax:Bug in geometria Hit-Testing

"m106,59.3c0-1.98,0,0-4.95,0.989-3.96, 0.989-13.8,3.96-20.8,4.95-6.92,0-14.8-3.96-17.8-3.96-1.98,2.97,3.96,10.9,7.91,13.8,2.97,1.98,9.89,3.96,14.8,3.96,4.95-0.989, 10.9-2.97,13.8-6.92,2.97-2.97,5.93-10.9,6.92-12.9z"

Per rendere la visuale io uso MyCanvas di classe, che fornisce funzionalità di testing ha colpito:

public class MyCanvas : Panel 
{ 
    public List<Visual> Visuals = new List<Visual>(); 
    private List<DrawingVisual> Hits = new List<DrawingVisual>(); 

    public void AddVisual(Visual Visual) 
    { 
     this.Visuals.Add(Visual); 
     base.AddVisualChild(Visual); 
     base.AddLogicalChild(Visual); 
    } 

    public List<DrawingVisual> GetVisuals(Geometry Region) 
    { 
     GeometryHitTestParameters Parameters = new GeometryHitTestParameters(Region); 
     this.Hits.Clear(); 
     HitTestResultCallback Callback = new HitTestResultCallback(this.HitTestCallBack); 
     VisualTreeHelper.HitTest(this, null, Callback, Parameters); 

     return this.Hits; 
    } 

    private HitTestResultBehavior HitTestCallBack(HitTestResult Result) 
    { 
     GeometryHitTestResult GeometryRes = (GeometryHitTestResult)Result; 
     DrawingVisual DVisual = Result.VisualHit as DrawingVisual; 

     if (DVisual != null && GeometryRes.IntersectionDetail == IntersectionDetail.FullyInside) 
      this.Hits.Add(DVisual);  

     return HitTestResultBehavior.Continue; 
    } 

    protected override Visual GetVisualChild(int Index) 
    { return this.Visuals[Index]; } 

    protected override int VisualChildrenCount { 
     get { return this.Visuals.Count; } 
    } 
} 

quando disegno il mio (rosso) percorso questo è il risultato:

Se le dimensioni delle celle della griglia è 50x50. Ora provo ad ottenere immagini per esempio in questa regione:

MyCanvas my_canvas = new MyCanvas(); 
RectangleGeometry MyRegion = new RectangleGeometry(new Rect(50, 50, 250, 250)); 
DrawingVisual MyPath = new DrawingVisual(); 

using (DrawingContext context = MyPath.RenderOpen()) { 
    context.PushTransform(new TranslateTransform(50, 50)); 
    context.PushTransform(new ScaleTransform(2, 2)); 
    context.DrawGeometry(Brushes.Red, new Pen(), MyGeometry); 
} 

my_canvas.AddVisual(MyPath); 
List<DrawingVisual> result = my_canvas.GetVisuals(MyRegion); 

Ma MyPath non è in risultato, perché? Come devo fare correttamente il hit-test? Grazie.

+0

Hai controllato se il percorso viene colpito nel tuo HitTestCallback (imposta un punto di interruzione)? Se lo è, quale valore ha IntersectionDetail? – Clemens

+0

Modifica la domanda (ho dimenticato le trasformazioni) comunque: IntersectionDetail.Intersect – gliderkite

+0

@Clemens Potrei aver trovato [qualcosa] (http://stackoverflow.com/questions/10453095/rendertransform-vs-pushtransform). – gliderkite

risposta

5

Sembra che hit-test consideri la posizione delle forme a cui è stato applicato un reverse order of transformations. Ciò spiegherebbe perché il mio percorso è solo intersecato e non fully inside l'argomento RectangleGeometry del metodo MyCanvas.GetVisuals.

In attesa di una risposta migliore, ho implementato il hit-test con un non hit-test metodo, ora parte di MyCanvas classe:

public List<DrawingVisual> GetVisuals(Rect Area) 
{ 
    this.Hits.Clear(); 

    foreach (DrawingVisual DVisual in this.Visuals) { 
     if (Area.Contains(DVisual.DescendantBounds)) 
      this.Hits.Add(DVisual); 
    } 

    return this.Hits; 
} 

EDIT:

Come spiega Mike Danes (moderatore sul forum MSDN) nel thread this:

"È davvero possibile che si tratti di un bug nella geometria hit-testing?"

Sono sicuro al 99% che si tratta di un bug. I test di disegno e hit dovrebbero utilizzare lo stesso ordine di trasformazione. Il motivo per cui funziona correttamente con TransformGroup è perché in questo modo si spinge solo una trasformazione nel contesto del disegno e questo evita l'ordine di moltiplicazione errato nel contesto del disegno di prova. Si noti che questo non ha nulla a che fare con il fatto che l'ordine utilizzato in TranformGroup è diverso dall'ordine push.

+0

Puoi archiviare questo bug con Microsoft da qualche parte? – DaveInCaz