• WPF Interaction框架简介(一)——Behavior


    在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();
            }
        }
    View Code

    上面的代码同样实现了一个将控件水平方向倾斜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 += onMouseDown;
                AssociatedObject.MouseMove += onMouseMove;
    
                AssociatedObject.MouseLeftButtonUp += onMouseUp;
                AssociatedObject.MouseEnter += onDragEnter;
            }
    
            protected override void OnDetaching()
            {
                AssociatedObject.MouseLeftButtonDown -= onMouseDown;
                AssociatedObject.MouseMove -= onMouseMove;
    
                AssociatedObject.MouseLeftButtonUp -= onMouseUp;
                AssociatedObject.MouseEnter -= onDragEnter;
    
                base.OnDetaching();
            }
    
            Point? start;
            private void onMouseDown(object sender, MouseButtonEventArgs e)
            {
                start = Mouse.GetPosition(_parent);
            }
    
            private void onMouseMove(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 onMouseUp(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);
            }
        }
    View Code
  • 相关阅读:
    C语言I博客作业02
    C语言I博客作业06
    C语言I—2019秋作业第一周作业
    C语言I博客作业09
    C语言I博客作业07
    C语言I博客作业08
    利用 jrebel 热部署\远程调试\远程热部署 springboot项目 服务器上的代码
    java 双因素认证(2FA)TOTP demo
    java File读取文件始终不存在的问题分析
    exchange 2010 的两个错误
  • 原文地址:https://www.cnblogs.com/TianFang/p/4215790.html
Copyright © 2020-2023  润新知