Что мне не хватает в этом RoutedEvent?

В настраиваемом FrameworkElement (a Shape) у меня есть:

public static readonly RoutedEvent DragDeltaEvent = EventManager.RegisterRoutedEvent("DragDelta", RoutingStrategy.Bubble, typeof(DragDeltaEventHandler), typeof(MyShape));
public event DragDeltaEventHandler DragDelta { add { AddHandler(DragDeltaEvent, value); } remove { RemoveHandler(DragDeltaEvent, value); } }

// xaml DataTemplate:
    <local:MyShape DragDelta="MyShape_DragDelta" />

Приведенный выше AddHandler не вызывается при создании фигур (в DataTemplate).
Я никогда не получаю событие в коде позади, когда я запускаю его в своей форме:

RaiseEvent(new DragDeltaEventArgs(...);

person Gerard    schedule 21.02.2014    source источник
comment
AddHandler не вызывается, потому что WPF будет вызывать его напрямую, а не через оболочку, как _2 _ / _ 3_ для DependencyProperty, но помимо этого он должен работать. По крайней мере, здесь на моем примере это работает   -  person dkozl    schedule 21.02.2014
comment
О да, в этом есть смысл. Но в моем случае RaiseEvent не доходит до обработчика MyShape_DragDelta в коде позади.   -  person Gerard    schedule 21.02.2014
comment
Итак, где-то внутри MyShape у вас есть RaiseEvent(new DragDeltaEventArgs(MyShape.DragDeltaEvent)), который, я полагаю, вы проверили, выполняется, а MyShape_DragDelta не вызывается.   -  person dkozl    schedule 21.02.2014
comment
Да, я попал в этот RaiseEvent(new DragDeltaEventArgs(2,2); (2,2 в качестве примера), но без сбоев в коде.   -  person Gerard    schedule 21.02.2014
comment
Может быть проблема с именованием, возможно, имя DragDeltaEventArgs уже занято, или я должен добавить владельца?   -  person Gerard    schedule 21.02.2014
comment
Я скопировал ваш код, все так же названо. Единственная разница в том, что я использовал Border вместо Shape в качестве базового класса, и я использовал его в ListBox.ItemTemplate   -  person dkozl    schedule 21.02.2014
comment
Я повторно использовал код из MS Thumb.cs, чтобы, так сказать, сделать ShapeThumb. Возможно, эти события + аргументы нельзя использовать за пределами Thumb.   -  person Gerard    schedule 21.02.2014
comment
Это объяснило бы вашу проблему. Вы не передаете RoutedEvent в DragDeltaEventArgs (потому что он не позволяет вам), поэтому он будет вызывать Thumb.DragDelta, а не MyShape.DragDelta   -  person dkozl    schedule 21.02.2014
comment
Я проверил, теперь он работает. Я опубликую решение, чтобы другие могли извлечь выгоду.   -  person Gerard    schedule 21.02.2014


Ответы (1)


Типичный код для определения обработчика событий и соответствующих аргументов событий:

public class DeltaEventArgs : RoutedEventArgs
{
        public DeltaEventArgs(double horizontalChange, double verticalChange) : base()
        {
            _horizontalChange = horizontalChange;
            _verticalChange = verticalChange;
            RoutedEvent = MyShape.DragDeltaEvent;
        }

        public double HorizontalChange
        {
            get { return _horizontalChange; }
        }

        public double VerticalChange
        {
            get { return _verticalChange; }
        }

        protected override void InvokeEventHandler(Delegate genericHandler, object genericTarget)
        {
            DeltaEventHandler handler = (DeltaEventHandler)genericHandler;

            handler(genericTarget, this);
        }

        private double _horizontalChange;
        private double _verticalChange;
    }

    public delegate void DeltaEventHandler(object sender, DeltaEventArgs e);

Я повторно использовал код из класса Thumb фреймворка, чтобы создать своего рода форму «большого пальца».
Но тогда вы не сможете повторно использовать обработчики событий и аргументы событий, потому что они предназначены специально для класса Thumb.

Когда вы используете обычную фигуру в качестве шаблона данных и окружаете ее обычным пальцем, перетаскивание часто становится нерегулярным (см. этот вопрос ). Пытаюсь исправить такое поведение.

person Gerard    schedule 21.02.2014