-->

SL4/MVVM: Handle MouseDragElementBehavior.Dragging

2019-01-28 10:37发布

问题:

I am trying to handle the MouseDragElementBehavior.Dragging event on a control I have. See here for background on why I want to do this.

I am having trouble wiring up this event. From the XAML you can see I have added a behavior to the user control. Then I attempted to add a handler to the Dragging event on the behavior via the CallMethodAction EventTrigger.

<i:Interaction.Behaviors>
    <ei:MouseDragElementBehavior ConstrainToParentBounds="True">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Dragging">
                <ei:CallMethodAction MethodName="NotifyChildrenYouAreDragging" TargetObject="{Binding}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </ei:MouseDragElementBehavior>
</i:Interaction.Behaviors>

I have tried the following method signatures with no luck:

void NotifyChildrenYouAreDragging(){}
void NotifyChildrenYouAreDragging(object sender, EventArgs e){}
void NotifyChildrenYouAreDragging(object sender, MouseEventArgs e){}

Anyone have experience using triggers to handle events in attached behaviors?

回答1:

The problem is that the EventTrigger doesn't hook up to the Behavior's events. Instead it is hooking up to the Behavior's AssociatedObject's events. Here is the relevant source code:

 protected override void OnAttached()
    {
        base.OnAttached();
        DependencyObject associatedObject = base.AssociatedObject;
        Behavior behavior = associatedObject as Behavior;
        FrameworkElement element = associatedObject as FrameworkElement;
        this.RegisterSourceChanged();
        if (behavior != null)
        {
            associatedObject = ((IAttachedObject) behavior).AssociatedObject;
            behavior.AssociatedObjectChanged += new EventHandler(this.OnBehaviorHostChanged);
        }
        ....
  }

So you can see that if the associated object of the trigger is a behavior, then it sets the associated object to the Behavior's associated object which is your items collection. The items collection doesn't have a dragging event so nothing is ever fired.

You could probably get the results you want by creating another behavior that checks to see if the associated object has a drag behavior and if so have your behavior attach to the dragging event. Then call the method on the object from there.