首页 > 其他分享 >wpf中Interaction.Behaviors详解

wpf中Interaction.Behaviors详解

时间:2023-02-02 23:15:03浏览次数:58  
标签:Behaviors 控件 Interaction Interactions void AssociatedObject 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();
        }
    }
 

上面的代码同样实现了一个将控件水平方向倾斜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);
        }
    }

标签:Behaviors,控件,Interaction,Interactions,void,AssociatedObject,start,Behavior,wpf
From: https://www.cnblogs.com/lzjsky/p/17087684.html

相关文章

  • WPF调用winfrom控件
    1.导包在引用处添加System.Windows.Fotms和WindowsFormslntegration2.xaml部分在需要使用控件的页面添加引用xmlns:wf="clr-namespace:System.Windows.Forms;assembly=......
  • WPF有用的最基础整理
    日常使用最多的控件有6类:1.布局控件:可以容纳多个控件或嵌套其他布局控件,例如Grid、StackPanel、DockPanel等,有共同的父类Panel2.内容控件:只能容纳一个其他控件或布局......
  • 【gRPC】.NET 6 WPF gRPC client 无法找到命名空间生成项目失败
    基于.NET6的WPF项目作为gRPC客户端,生成项目时出错:1>D:\projects\aasp_pc_soft\AutonomicAnalysisSystemForPressurePellets\AutoAnalysisSystemClientTest\AutoAnalysis......
  • WPF控件模板查看
    背景在使用WPF的过程中,经常需要对控件的外观进行定制,这个时候查看其原有的样式或者模板进行参考就很有必要了。这样一能够减少许多工作,只修改需要的部分,二能够避免修改模......
  • Revit二次开发针对类库项目中WPF界面如何引用第三方控件库HandyControl的方法
    起因是当使用类库作为WPF界面的项目时,项目中没有App.xaml,也就导致没有办法在全局资源中统一设置HandyControl的资源。解决方案很简单安装完HandyControl库后,在Window中加......
  • 【WPF】Button使用汇总
    一、通过双击或者快捷键触发Command事件<ButtonContent="Button"><Button.InputBindings><MouseBindingMouseAction="LeftDoubleClick"......
  • WPF中下拉框即可以选择项也可以作为只读文本框使用
    1、需求当前在开发的系统需要一个这样的控件。(1)可以选择已有的选择项,类似于ComboBox选择;(2)可以通过其他按钮点击,选择一个文件,选择后,把文件路径显示到控件上,并且处于只读......
  • WPF开发经验-实现一种三轴机械手控件
    一引入 考虑实现一种三轴机器人控件。三轴机器人用来将某种工件从一个位置运送到另一个位置。其X轴为手臂轴,可以正向和反向运动,它处于末端,直接接触工件;其T轴为旋转......
  • WPF DispatcherUnhandledException 异常捕获最后的大门
    这里在界面按钮事件下除0测试,感觉软件还是退出了?///<summary>///App.xaml的交互逻辑///</summary>publicpartialclassApp:Application{protectedove......
  • 深入浅出WPF的命令系统
    1.什么是命令?我们通过一个场景来说明这个问题。假设某天某个时间点,公司领导对小王说:“小王,去前台帮我取一下快递。”这里,领导对小王所说的话就可以理解为命令,简而言之,命令......