zoukankan      html  css  js  c++  java
  • WPF之Behavior

    本文主要是以实现拖动元素作为例子。

    创建Behavior:

    通常这个类会继承自Behavior<T>,其中T就是此Behavior服务的对象,在此处使用的是UIElement,也就是虽有的UIElement类型的元素都可以使用。

     public class DragInCanvasBehavior : Behavior<UIElement>
        {
            //元素父节点
            private Canvas canvas;
            //标识是否进入拖动
            private bool isDraging = false;
            //按下鼠标时的坐标(用于计算要移动的位置)
            private Point mouseOffset;
    
            /// <summary>
            /// 附加行为后
            /// </summary>
            protected override void OnAttached()
            {
                base.OnAttached();
                //添加鼠标事件(AssociatedObject也就是当前应用此Behavior的元素)
                this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
                this.AssociatedObject.MouseMove += AssociatedObject_MouseMove;
                this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
            }
    
            void AssociatedObject_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                //释放拖动状态
                isDraging = false;
            }
    
            void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
            {
                //如果进入拖动状态
                if (isDraging)
                {
                    //得到新的位置
                    Point newPoint = e.GetPosition(canvas);
                    //旧的坐标加上新坐标和旧坐标的差
                    mouseOffset.X += newPoint.X - mouseOffset.X;
                    mouseOffset.Y += newPoint.Y - mouseOffset.Y;
    
                    //设置元素的Left和Top,之所以要用X(Y)减去Width(Height),主要是为了使鼠标在元素中心
                    Canvas.SetLeft(this.AssociatedObject, mouseOffset.X-(this.AssociatedObject as FrameworkElement).ActualWidth/2);
                    Canvas.SetTop(this.AssociatedObject, mouseOffset.Y - (this.AssociatedObject as FrameworkElement).ActualHeight/2);
                }
            }
    
            void AssociatedObject_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                //将元素的父节点元素赋值为Canvas(之所以使用Canvas,是因为Canvas容易动态布局)
                if (canvas == null)
                    canvas = (Canvas)VisualTreeHelper.GetParent(this.AssociatedObject);
                //进入拖动状态
                isDraging = true;
                //获得初始位置
                mouseOffset = e.GetPosition(this.AssociatedObject);
                this.AssociatedObject.CaptureMouse();
            }
    
            /// <summary>
            /// 分离行为
            /// </summary>
            protected override void OnDetaching()
            {
                //移除鼠标事件
                this.AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
                this.AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
                this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
            }
        }

     在WPF中实现拖动,一般只需三个事件即可,MouseLeftButtonDown、MouseLeftButtonUp、MouseMove。Down事件负责进入拖动状态,并且记录初始的鼠标坐标(用于拖动中动态修改元素的位置),同时也要得到当前元素的Parent即Canvas,这样才可以在Move时候获得相对于Canvas的新坐标;Up事件负责状态变为正常,这时候在移动就没变化的;Move事件负责的事情比较重要,得到当前鼠标相对于Canvas的新坐标,然后和旧坐标进行计算,最后设置元素的新坐标。

    使用Behavior:

     注:如果你还没有引用Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll,那么赶紧引用进来吧(如果你么有安装Blend,那么就点击下载吧)。

    <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
            xmlns:behavior="clr-namespace:CustomBehaviorsLibrary;assembly=CustomBehaviorsLibrary"
            Title="MainWindow" Height="350" Width="525">
        <Canvas Background="LightBlue">
            <Rectangle Height="50" Width="50" Fill="Green" >
                <i:Interaction.Behaviors>
                    <behavior:DragInCanvasBehavior></behavior:DragInCanvasBehavior>
                </i:Interaction.Behaviors>
            </Rectangle>
        </Canvas>
    </Window>

    添加对Interactivity和Behavior所属程序及的引用,页面内容很简单,一个Canvas包含一个Rectangle,在Rectangle中设置Behaviros为创建的Behavior,这样神奇的事情就发生了,运行程序,拖动Rectangle,就可以看到可以改变位置了哦。

    注:由于本文的示例Behavior和WPF应用程序是分离的,所以在此需要添加对Behavior所在类库的引用,同时在Window标签中添加对Behavior所属Assembly的引用,如果你的Behavior和XAML在同一个程序集,则可以进行适当的修改。

    XAML中Trigger和Action组合之后应该是等同于一个Behavior,可以参见本人另一篇日志(Silverlight之Styles和Behaviors)。

    希望大家多提意见和建议,如果评论,我会在第一时间回复。

  • 相关阅读:
    生产上第一使用线程池后的总结与反思
    20190407
    20190403
    Asp.net MVC中的ViewData与ViewBag
    easyui datagrid分页
    EF从数据库更新模型更新不到新表
    C语言 笔记(函数)
    python 写100~1000以内水仙花数
    python 求前n项阶乘的和
    python 写九九乘法表
  • 原文地址:https://www.cnblogs.com/ListenFly/p/3275289.html
Copyright © 2011-2022 走看看