0

In a custom FrameworkElement (a Shape) I have:

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" />

The AddHandler above is not invoked when the shapes (in a DataTemplate) are created.
I never receive the event in code behind when I fire it in my shape by:

RaiseEvent(new DragDeltaEventArgs(...);
evanb
  • 3,061
  • 20
  • 32
Gerard
  • 13,023
  • 14
  • 72
  • 125
  • 1
    `AddHandler` is not called because WPF will call it directly, not via wrapper, same as `SetValue`/`GetValue` for `DependencyProperty` but apart from that it should work. At least it works here on my example – dkozl Feb 21 '14 at 14:35
  • O yes that makes sense. But in my case `RaiseEvent` does not reach the handler `MyShape_DragDelta` in code behind. – Gerard Feb 21 '14 at 14:41
  • So somewhere inside `MyShape` you have `RaiseEvent(new DragDeltaEventArgs(MyShape.DragDeltaEvent))`, which I assume you checked is executed, and `MyShape_DragDelta` is not being called. – dkozl Feb 21 '14 at 14:47
  • Yes I hit that `RaiseEvent(new DragDeltaEventArgs(2,2);` (2,2 as example), but no break in code behind. – Gerard Feb 21 '14 at 14:49
  • Could it be a naming issue, perhaps name `DragDeltaEventArgs` is already occupied, or I should add an owner? – Gerard Feb 21 '14 at 14:54
  • I've copied your code, everything is named the same way. The only difference is I've used `Border` instead of `Shape` as base class and I've used it in `ListBox.ItemTemplate` – dkozl Feb 21 '14 at 15:16
  • I reused code from MS Thumb.cs to make a ShapeThumb so to speak. Perhaps those events+args cannot be used outside `Thumb`. – Gerard Feb 21 '14 at 15:25
  • 1
    This would explain your problem. You don't pass `RoutedEvent` to `DragDeltaEventArgs` (because it does not let you) so it will call `Thumb.DragDelta` and not `MyShape.DragDelta` – dkozl Feb 21 '14 at 15:33
  • I checked it and it works now. I will post the solution so others can benefit. – Gerard Feb 21 '14 at 15:39

1 Answers1

1

Typical code for eventhandler definition and corresponding eventarguments are:

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);

I reused code from the frameworks Thumb class to create a kind of "thumb" shape.
But you then cannot reuse the eventhandlers and event-arguments, because they are specifically for the Thumb class.

When you use a regular Shape as a DataTemplate and surrond it with a regular Thumb the dragging becomes often irregular (comp. this question). Trying to repair that behaviour.

Community
  • 1
  • 1
Gerard
  • 13,023
  • 14
  • 72
  • 125