2010-11-18 19 views
5

Tengo una forma de línea personalizada que usa un adorno para mostrar una matriz y algo de texto en el medio de esa línea.Adorner and Events on Adorned element

alt text

El problema es que el adornada se comporta de forma independiente del elemento adornada, y no lo hace "transferencia", el evento a la misma. En el siguiente código me veo obligado a volver a vincular manualmente los elementos adornados al elemento adornado (ta.MouseLeftButtonDown += Adorner_MouseLeftButtonDown;), pero desafortunadamente incluso esto no funciona ... ¿Podría alguien aconsejar qué está mal al llamar a this.OnMouseLeftButtonDown, por qué no recibo el evento respectivo?

public class SegmentLine : Shape 
{ 
    AdornerLayer aLayer; 

    public static readonly DependencyProperty X1Property; 
    public static readonly DependencyProperty X2Property; 
    public static readonly DependencyProperty Y1Property; 
    public static readonly DependencyProperty Y2Property; 
    ... 

    static SegmentLine() { 
     X1Property = DependencyProperty.Register("X1", typeof(double), typeof(SegmentLine), new FrameworkPropertyMetadata(double.NaN, 
      FrameworkPropertyMetadataOptions.AffectsRender)); 
     X2Pro... 
    } 

    public SegmentLine() 
     : base() 
    { 
     this.Loaded += SegmentLine_Loaded; 
    } 

    void SegmentLine_Loaded(object sender, RoutedEventArgs e) 
    { 
     aLayer = AdornerLayer.GetAdornerLayer(this); 
     if (aLayer != null) 
     { 
      TextAdorner ta = new TextAdorner(this); 
      //ta.IsHitTestVisible = false; 
      ta.MouseLeftButtonDown += Adorner_MouseLeftButtonDown; 
      aLayer.Add(ta); 
     } 
    } 

    void Adorner_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     // !! try to rise the MouseLeftButtonDown event 
     this.OnMouseLeftButtonDown(e); 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 
     if (aLayer != null) 
      aLayer.Update(); 
    } 

    class TextAdorner : Adorner 
    { 
     public TextAdorner(UIElement adornedElement) 
      : base(adornedElement) { } 

     protected override void OnRender(DrawingContext drawingContext) 
     { 
      // ADD LABEL ... 
      FormattedText ft = new FormattedText(...); 
      drawingContext.DrawText(ft, midPoint); 

      // Add ARROW ... 
      var myPathGeometry = new PathGeometry { Figures = myPathFigureCollection };    
      drawingContext.DrawGeometry(Brushes.Black, null, myPathGeometry); 
     } 
    } 

    protected override System.Windows.Media.Geometry DefiningGeometry 
    { 
     get 
     { 
      var geometryGroup = new GeometryGroup(); 
      // Add line 
      geometryGroup.Children.Add(new LineGeometry(new Point(X1, Y1), new Point(X2, Y2))); 
      return geometryGroup; 
     } 
    }  
} 
+1

Puede deshabilitar todos los eventos en adornador simplemente estableciendo 'IsHitTestVisible' en falso. ¿O quieres que algunos eventos sean manejados por Adornner y otros por 'SegmentLine'? –

+0

@ alpha-mouse: no, cualquier evento quiero que sea manejado por adorner, pero si configuro IsHitTestVisible = false (como se puede ver en el código) no recibo ningún evento. – serhio

Respuesta

5

Debe llamar this.RaiseEvent(e); en lugar de this.OnMouseLeftButtonDown(e); para transferir el caso al elemento adornada.
Y, por cierto, se puede utilizar un solo controlador de eventos para transferir varios tipos de eventos

void SegmentLine_Loaded(object sender, RoutedEventArgs e) 
{ 
    .. 
    ta.MouseLeftButtonDown += Adorner_AnyEvent; 
    ta.MouseRightButtonDown += Adorner_AnyEvent; 
} 

void Adorner_AnyEvent(object sender, RoutedEventArgs e) 
{ 
    this.RaiseEvent(e); 
} 
1

Sé que esto es viejo, pero tuve un problema similar (no recibe eventos en Adorner), que me fijo dibujando un fondo transparente en mi OnRender()

drawingContext.DrawRectangle(Brushes.Transparent, null, viewRect); 

No background = no events.