2011-01-27 14 views
10

Estoy obteniendo un control de FrameworkElement para usarlo como contenedor de una VisualCollection, ya que estoy haciendo muchas representaciones personalizadas usando DrawingVisuals (creando un mapa de juego).WPF UIElement.IsHitTestVisible = false; ¿Aún regresas éxitos?

Tengo un par de instancias diferentes de mi contenedor en capas una sobre otra, y solo quiero que la prueba de golpe afecte la capa actualmente visible, así que intenté hacer lo obvio, y establecí .IsHitTestVisible = false, que según MSDN, debe evitar que se devuelvan elementos secundarios como resultados de aciertos.

Sin embargo, todavía estoy recibiendo obtenidos en los contenedores que se establecen .IsHitTestVisible = false. He intentado todo lo demás que se me ocurre, Colapsado, Oculto, Inhabilitado, 0 Opacidad, nada parece sacarlo de la prueba de golpes.

+0

La única solución que he encontrado hasta ahora es eliminar realmente el control contenedor desde su colección primaria , por lo que está completamente fuera de la jerarquía de VisualTree. –

Respuesta

13

Creo que es un error. Utilicé Reflector para comprender por qué el método HitTest devuelve elementos invisibles y descubrí que no hay verificación de visibilidad.

Mi solución es utilizar HitTest sobrecarga con filtro:

public static HitTestFilterBehavior HitTestFilterInvisible(DependencyObject potentialHitTestTarget) 
{ 
    bool isVisible = false; 
    bool isHitTestVisible = false; 

    var uiElement = potentialHitTestTarget as UIElement; 
    if (uiElement != null) 
    { 
     isVisible = uiElement.IsVisible; 
     if (isVisible) 
     { 
      isHitTestVisible = uiElement.IsHitTestVisible; 
     } 
    } 
    else 
    { 
     UIElement3D uiElement3D = potentialHitTestTarget as UIElement3D; 
     if (uiElement3D != null) 
     { 
      isVisible = uiElement3D.IsVisible; 
      if (isVisible) 
      { 
       isHitTestVisible = uiElement3D.IsHitTestVisible; 
      } 
     } 
    } 

    if (isVisible) 
    { 
     return isHitTestVisible ? HitTestFilterBehavior.Continue : HitTestFilterBehavior.ContinueSkipSelf; 
    } 

    return HitTestFilterBehavior.ContinueSkipSelfAndChildren; 
} 
... 
// usage: 

    VisualTreeHelper.HitTest(
     myHitTestReference, 
     HitTestFilterInvisible, 
     hitTestResult => 
     { 
      // code to handle element which is visible to the user and enabled for hit testing. 
     }, 
     new PointHitTestParameters(myHitTestPoint)); 

espero que le ayudará a

+1

Aunque esperaba una forma de hacer que el comportamiento funcione como lo describe MSDN en lugar de una solución alternativa, esto fue útil, así que lo marcaré como la respuesta. –

+2

Tengo el mismo problema con un borde que es parte de mi plantilla de scrollviewer ... Tengo un borde en la parte inferior que crea una pequeña sombra "indirecta" para que el usuario sepa que el contenido es desplazable, pero el borde bloquea el mouse eventos del contenido debajo ... He establecido IsHitTestVisible = "false" en el borde, pero aún recibe eventos del mouse. Lamentablemente, no estoy tratando con ningún código detrás de los archivos, así que no puedo anular los métodos de prueba de éxito ... ¿alguna idea? – Valerie

Cuestiones relacionadas