代码之家  ›  专栏  ›  技术社区  ›  serhio

装饰器和装饰元素上的事件

  •  5
  • serhio  · 技术社区  · 14 年前

    我有一个自定义的线条形状,它使用一个装饰器来显示一个数组和该线条中间的一些文本。

    alt text

    问题是修饰的行为独立于修饰的元素,并且不会将事件“转移”给它。在下面的代码中,我被迫手动将装饰器元素重新链接到装饰元素( ta.MouseLeftButtonDown += Adorner_MouseLeftButtonDown; ),但不幸的是,即使这样也不起作用。。。 有人能告诉我在调用this.OnMouseLeftButtonDown时出了什么问题吗?为什么我没有收到相应的事件?

    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;
            }
        }    
    }
    
    2 回复  |  直到 14 年前
        1
  •  5
  •   alpha-mouse    14 年前

    你应该打电话 this.RaiseEvent(e); 而不是 this.OnMouseLeftButtonDown(e); 将事件传输到修饰元素。
    顺便说一下,您只能使用一个事件处理程序来传输多个事件类型

    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);
    }
    
        2
  •  1
  •   GazTheDestroyer    12 年前

    我知道这是一个老问题,但我有一个类似的问题(不在装饰器中接收事件),我通过在OnRender()中绘制透明的背景来解决了这个问题

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

    无背景=无事件。