ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

wpf中Interaction.Behaviors详解

2020-09-02 23:33:23  阅读:939  来源: 互联网

标签:Behaviors Interaction parent void AssociatedObject transForm start Behavior wpf


在WPF 4.0中,引入了一个比较实用的库——Interactions,这个库主要是通过附加属性来对UI控件注入一些新的功能,除了内置了一系列比较好用的功能外,还提供了比较良好的扩展接口。本文这里简单的介绍一下Behavior这个扩展。

顾名思义,Behavior可以赋予控件新的行为能力,例如,我们可以通过MouseDragElementBehavior给控件附加上支持拖放的能力。使用方式如下:

  1. 添加Interactions库的引用。主要添加如下两个DLL:Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll。
  2. 添加如下名字空间

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

  3. 在控件中添加MouseDragElementBehavior
    <Image Source="2.jpg" >
        <i:Interaction.Behaviors>
            <ei:MouseDragElementBehavior/>
        </i:Interaction.Behaviors>
    </Image>

 这三步中前面几步都是添加Interactions库的支持,对于后面介绍的Trigger和Action也是一样的,只有<ei:MouseDragElementBehavior/>一句才是和Behavior相关的。实际上,我们可以通过在Blend里直接将MouseDragElementBehavior拖放到控件上简化这一过程。加上MouseDragElementBehavior后,我们的控件就支持鼠标拖拽移动了,非常给力。

实际上,系统还提供了一系列非常好用的Behavior,后面我再单独写文章来介绍它。 

编写自己的Behavior

除了系统自己提供的Behavior外,我们也可以通过自己编写Behavior来实现自定义行为,一个简单的示例如下:  

 class SkewBehavior : Behavior<UIElement>
    {
        SkewTransform _transForm;

        protected override void OnAttached()
        {
            base.OnAttached();

            _transForm = new SkewTransform();

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

        protected override void OnDetaching()
        {
            _transForm.AngleX = 0;
            base.OnDetaching();
        }
    }
复制代码
    class SkewBehavior : Behavior<UIElement>
    {
        SkewTransform _transForm;

        protected override void OnAttached()
        {
            base.OnAttached();

            _transForm = new SkewTransform();

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

        protected override void OnDetaching()
        {
            _transForm.AngleX = 0;
            base.OnDetaching();
        }
    }
复制代码

上面的代码同样实现了一个将控件水平方向倾斜30度的Behavior(实现得比较简单,并不完善),大体上关键的地方有如下三个:

  1. 通过AssociatedObject属性获取附加的对象。
  2. 通过重载OnAttached函数进行Behavior附加上时的初始化操作
  3. 通过重载OnDetaching函数进行移除Behavior时候的析构操作

虽然我们也可以直接通过附加属性实现这样的功能,但Interactions框架无疑规范并简化了这一行为。

最后,附上一个比较常用的鼠标拖放的Behavior,和内置的MouseDragElementBehavior不同的是,它产生鼠标事件,用于实现一些自定义的拖放操作:

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

        IInputElement _parent;

        protected override void OnAttached()
        {
            base.OnAttached();

            _parent = LogicalTreeHelper.GetParent(AssociatedObject) as IInputElement;

            if (_parent == null)
                return;

            AssociatedObject.MouseLeftButtonDown += onm ouseDown;
            AssociatedObject.MouseMove += onm ouseMove;

            AssociatedObject.MouseLeftButtonUp += onm ouseUp;
            AssociatedObject.MouseEnter += onDragEnter;
        }

        protected override void OnDetaching()
        {
            AssociatedObject.MouseLeftButtonDown -= onm ouseDown;
            AssociatedObject.MouseMove -= onm ouseMove;

            AssociatedObject.MouseLeftButtonUp -= onm ouseUp;
            AssociatedObject.MouseEnter -= onDragEnter;

            base.OnDetaching();
        }

        Point? start;
        private void onm ouseDown(object sender, MouseButtonEventArgs e)
        {
            start = Mouse.GetPosition(_parent);
        }

        private void onm ouseMove(object sender, MouseEventArgs e)
        {
            if (!start.HasValue)
                return;

            var p = Mouse.GetPosition(_parent);
            var offset = p - start.Value;

            start = p;

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


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

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

        void tryEndDrag()
        {
            if (Mouse.LeftButton != MouseButtonState.Released)
                return;

            start = null;

            Drop?.Invoke(AssociatedObject, EventArgs.Empty);
        }
    }
复制代码
    class DragDropBehavior : Behavior<UIElement>
    {
        public event EventHandler<DragDeltaEventArgs> DragDelta;
        public event EventHandler<EventArgs> Drop;

        IInputElement _parent;

        protected override void OnAttached()
        {
            base.OnAttached();

            _parent = LogicalTreeHelper.GetParent(AssociatedObject) as IInputElement;

            if (_parent == null)
                return;

            AssociatedObject.MouseLeftButtonDown += onm ouseDown;
            AssociatedObject.MouseMove += onm ouseMove;

            AssociatedObject.MouseLeftButtonUp += onm ouseUp;
            AssociatedObject.MouseEnter += onDragEnter;
        }

        protected override void OnDetaching()
        {
            AssociatedObject.MouseLeftButtonDown -= onm ouseDown;
            AssociatedObject.MouseMove -= onm ouseMove;

            AssociatedObject.MouseLeftButtonUp -= onm ouseUp;
            AssociatedObject.MouseEnter -= onDragEnter;

            base.OnDetaching();
        }

        Point? start;
        private void onm ouseDown(object sender, MouseButtonEventArgs e)
        {
            start = Mouse.GetPosition(_parent);
        }

        private void onm ouseMove(object sender, MouseEventArgs e)
        {
            if (!start.HasValue)
                return;

            var p = Mouse.GetPosition(_parent);
            var offset = p - start.Value;

            start = p;

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


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

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

        void tryEndDrag()
        {
            if (Mouse.LeftButton != MouseButtonState.Released)
                return;

            start = null;

            Drop?.Invoke(AssociatedObject, EventArgs.Empty);
        }
    }
复制代码

标签:Behaviors,Interaction,parent,void,AssociatedObject,transForm,start,Behavior,wpf
来源: https://www.cnblogs.com/happyShare/p/13605093.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有