SoFunction
Updated on 2025-03-07

WPF implements Behavior extension of Interaction framework

In WPF 4.0, a more practical library - Interactions, was introduced. This library mainly injects some new functions into UI controls through additional properties. In addition to a series of more useful functions built-in, it also provides a relatively good extension interface. This article briefly introduces the Behavior extension here.

As the name suggests, Behavior can give controls new behavioral capabilities. For example, we can attach the controls to the ability to support drag and drop through MouseDragElementBehavior. How to use it is as follows:

  • Add a reference to the Interactions library. The following two DLLs are mainly added: and.

  • Add the following namespace

    xmlns:i="/expression/2010/interactivity"
    xmlns:ei="/expression/2010/interactions"

  • Add MouseDragElementBehavior to the control

    <Image Source="" >
        <i:>
            <ei:MouseDragElementBehavior/>
        </i:>
    </Image>

The first few steps of these three steps are all supported by adding the Interactions library. The same is true for the Trigger and Action introduced later. Only the sentence <ei:MouseDragElementBehavior/> is related to Behavior. In fact, we can simplify this process by dragging and dropping the MouseDragElementBehavior directly onto the control in Blend. After adding MouseDragElementBehavior, our control supports mouse drag and move, which is very powerful.

In fact, the system also provides a series of very useful Behaviors, and I will write a separate article to introduce it later.

Write your own Behavior

In addition to the Behavior provided by the system itself, we can also implement custom behavior by writing Behaviors ourselves. A simple example is as follows:

    class SkewBehavior : Behavior<UIElement>
    {
        SkewTransform _transForm;

        protected override void OnAttached()
        {
            ();

            _transForm = new SkewTransform();

             = _transForm;
             = new Point(0.5, 0.5);
            _transForm.AngleX = 30;
        }

        protected override void OnDetaching()
        {
            _transForm.AngleX = 0;
            ();
        }
    }

The above code also implements a Behavior that tilts the control horizontally by 30 degrees (it is relatively simple and not perfect). Generally speaking, there are three key points:

  • Get the attached object through the AssociatedObject property.

  • Initialization operation when Behavior is attached by overloading the OnAttached function

  • Destruction operation when removing Behavior by overloading the OnDetaching function

Although we can also implement such functions directly through additional properties, the Interactions framework undoubtedly specifies and simplifies this behavior.

Finally, a more commonly used mouse drag and drop Behavior is attached. Unlike the built-in MouseDragElementBehavior, it generates mouse events and is used to implement some custom drag and drop operations:

    class DragDropBehavior : Behavior<UIElement>
    {
        public event EventHandler<DragDeltaEventArgs> DragDelta;
        public event EventHandler<EventArgs> Drop;

        IInputElement _parent;

        protected override void OnAttached()
        {
            ();

            _parent = (AssociatedObject) as IInputElement;

            if (_parent == null)
                return;

             += onMouseDown;
             += onMouseMove;

             += onMouseUp;
             += onDragEnter;
        }

        protected override void OnDetaching()
        {
             -= onMouseDown;
             -= onMouseMove;

             -= onMouseUp;
             -= onDragEnter;

            ();
        }

        Point? start;
        private void onMouseDown(object sender, MouseButtonEventArgs e)
        {
            start = (_parent);
        }

        private void onMouseMove(object sender, MouseEventArgs e)
        {
            if (!)
                return;

            var p = (_parent);
            var offset = p - ;

            start = p;

            DragDelta?.Invoke(AssociatedObject, new DragDeltaEventArgs(, ));
        }


        private void onMouseUp(object sender, MouseButtonEventArgs e)
        {
            tryEndDrag();
        }

        private void onDragEnter(object sender, MouseEventArgs e)
        {
            tryEndDrag();
        }

        void tryEndDrag()
        {
            if ( != )
                return;

            start = null;

            Drop?.Invoke(AssociatedObject, );
        }
    }

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.