WPF高级教程(十八)行为

介绍

在讲解到样式的时候我们说,样式是为了一系列元素共享一些属性而存在的,归根结底是为了复用代码和逻辑,而我们学习了触发器之后,发现我们可以用触发器写一些简单的逻辑到样式中,但是这种简单的逻辑有时候远远不够。

当我们要实现一堆元素支持在Cancas上面拖放,停靠,缩放等功能的时候,触发器就显得不是那么够用了。

我们在复用代码的时候,有下面三种方法,他们互相补充,构建了WPF的属性重用架构,在合适的场景下选择合适的方法可以极大的简化我们的开发工作

  • 样式,主要是属性的设置,用触发器写的简单的控件行为
  • 自定义控件,为了满足某一功能编写的可以公用的专职控件
  • 行为,封装了一些通用的用户界面功能的行为,可以是十分复杂的功能的集合,一旦创建成功,可以将这种构建好的行为用于任意一个其他控件中,十分的强大

依赖

行为的必须依赖 System.Windows.Interactivity,我们在使用的时候可以从网上下载后,添加打项目中,通过引用该dll,引入对于System.Windows.Interactivity的依赖。这一步也是必须的

编写行为

我们通过一个例子,直观的看一下行为能够做什么,为什么它比触发器更加的强大

我们就编写之前提到过的,我们要通过写一个行为,让一些原本很普通的控件具备在Canvas上被拖动的能力,行为的编写如下

public class DragInCanvasBehavior : Behavior
{
    private Canvas canvas;
    private bool isDragging = false;
    private Point mouseOffset;



    protected override void OnAttached()
    {
        base.OnAttached();
        // 绑定事件处理
        this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
        this.AssociatedObject.MouseMove += AssociatedObject_MouseMove;
        this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
    }

    private void AssociatedObject_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        if (isDragging)
        {
            // 释放鼠标捕获
            AssociatedObject.ReleaseMouseCapture();
            isDragging = false;
        }
    }

    private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (isDragging)
        {
            // 获取控件在canvas上的位置
            Point point = e.GetPosition(canvas);
            // 移动鼠标的时候确定元素的新位置
            AssociatedObject.SetValue(Canvas.TopProperty, point.Y - mouseOffset.Y);
            AssociatedObject.SetValue(Canvas.LeftProperty, point.X - mouseOffset.X);
        }
    }

    private void AssociatedObject_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // 如果canvas不存在,查找canvas
        if (canvas == null)
        {
            canvas = (Canvas)VisualTreeHelper.GetParent(this.AssociatedObject);
        }
        //开始拖动
        isDragging = true;
        // 获取鼠标点击控件开始拖动的起始位置
        mouseOffset = e.GetPosition(AssociatedObject);
        // 使得我们要拖动的元素持续的获取MouseMove事件
        AssociatedObject.CaptureMouse();
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        // 移除事件处理
        this.AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
        this.AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
        this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
    }
}

需要注意:

  • 要使用行为,必须依赖 System.Windows.Interactivity
  • 我们一般都是要复写 OnAttach 和 OnDetaching 两个方法,用于在组件关联以及解除关联的时候,进行事件的监听和移除监听
  • 监听了我们感兴趣的事件之后,就可以在事件的处理方法之中写上控件的行为

写出了行为之后,我们需要将行为附加到元素上去,使用下面的方法


    
        

        
            
                
            
        
    

需要注意的是:

  • xaml中同样需要引入 Interactivity
  • 只需要简单的将行为附加于控件,就实现了行为中写入的功能,十分的方便

Blend 支持

我们在编程的时候,如果使用Blend构建页面,如果写过一个行为之后,可以在Blend的资产面板中找到这个行为,直接拖放,就可以给一个元素添加我们新写的行为。
WPF高级教程(十八)行为_第1张图片

你可能感兴趣的:(WPF,C#)