WPF中的Behavior及Behavior在MVVM模式下的应用

news2024/9/22 0:31:00

WPF中的Behavior及Behavior在MVVM模式下的应用

在WPF中,Behaviors(行为)是一种可重用的组件,可以附加到任何UI元素上,以添加特定的交互行为或功能。Behaviors可以通过附加属性或附加行为的方式来实现。

Behavior并不是WPF组件中的内容,需要安装nuget包,使用行为需要nuget安装Microsoft.Xaml.Behaviors.Wpf,FrameWork版本安装System.Windows.Interactivity.WPF,同时添加命名空间xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

使用Interaction.Behaviors

<Border
    Width="100"
    Height="100"
    Background="Red">
    <!--直接使用Behavior实现可拖拽Border-->
    <i:Interaction.Behaviors>
        <i:MouseDragElementBehavior />
    </i:Interaction.Behaviors>
</Border>

官方内置了以下几种Behavior,可以根据需要使用。

image-20230628100112094

自定义Behavior

可以根据需要,自定义Behavior,下面是一个鼠标触发MouseEnter事件改变背景色的Behavior

class MyBehavior:Behavior<Border>//必须制定泛型类型,因为某些属性是针对特定类型的
{
    //要重写两个方法
    //OnAttached()表示当挂载到对应的对象上的时候触发
    //OnDetaching()在对象销毁时触发
    protected override void OnAttached()
    {
        //AssociatedObject表示关联的对象
        AssociatedObject.MouseEnter += (_, _) => AssociatedObject.Background = Brushes.Orange;
    }
    protected override void OnDetaching()
    {
        base.OnDetaching();
    }
}
<Border
    Width="100"
    Height="100"
    Background="Red">
    <!--可以应用多个Behavior-->
    <i:Interaction.Behaviors>
        <i:MouseDragElementBehavior />
        <local:MyBehavior />
    </i:Interaction.Behaviors>
</Border>

9

案例:实现自动清空文本框内容

class ClearTextBehavior : Behavior<Button>
{

	//依赖属性,制定清空哪个文本框
    public TextBox Target
    {
        get { return (TextBox)GetValue(TargetProperty); }
        set { SetValue(TargetProperty, value); }
    }

    public static readonly DependencyProperty TargetProperty =
        DependencyProperty.Register("Target", typeof(TextBox), typeof(ClearTextBehavior), new PropertyMetadata(null));


    protected override void OnAttached()
    {
        AssociatedObject.Click += AssociatedObject_Click;
    }

    private void AssociatedObject_Click(object sender, RoutedEventArgs e)
    {
        Target?.Clear();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Click -= AssociatedObject_Click;
    }
}
<TextBox x:Name="tbx" />
<Button Width="30" Content="清空">
    <i:Interaction.Behaviors>
        <local:ClearTextBehavior Target="{Binding ElementName=tbx}" />
    </i:Interaction.Behaviors>
</Button>

10

使用Interaction.Triggers

使用EnentTrigger实现点击button关闭整个窗口

<Button Content="Close">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <!--一定要设置TargetObject不然默认的对象为dataContext-->
            <i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

同样,可以应用多个Trigger

<Button Content="Close">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
        </i:EventTrigger>
        <!--实现鼠标悬浮后改变颜色-->
        <i:DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=IsMouseOver}" Value="True">
            <i:ChangePropertyAction
                PropertyName="Background"
                TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Button}}"
                Value="Red" />
        </i:DataTrigger>
    </i:Interaction.Triggers>
</Button>

还可以使用Command与VM绑定

<Button Width="150" Height="50" Content="Interaction.Triggers">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:InvokeCommandAction Command="{Binding myCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

官方内置了以下几种Trigger,可以根据需要使用。

2023-06-28_095253

Style中的Trigger和控件中的Trigger

Style中的各种Trigger参见WPF的Style

继承自FrameworkElement类中控件也可以直接使用trigger

<Button
    Width="150"
    Height="100"
    Content="Button.Triggers">
    <Button.Triggers>
        <EventTrigger RoutedEvent="MouseEnter">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation
                        Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                        To="Red"
                        Duration="0:0:0:5" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

11

可以看出无论是Style中的Trigger还是控件下面的Trigger,都是使用的RoutedEvent属性来设置事件,但是有些事件是不属于RoutedEvent的,比如listbox的选择某个条目事件。而且这两种Trigger都是对故事板进行操作。

MVVM模式来实现获得鼠标的坐标

当鼠标在窗口上移动时,将坐标信息传到VM中,并在V中显示。那有人会问,这样还不如直接不经过VM直接在V中进行显示,关键在于,某些时候VM中需要坐标信息,而且要遵循MVVM模式。

  1. 自定义Behavior
class PositionBehavior : Behavior<Window>
{

   //设置两个依赖属性
    public double X
    {
        get { return (double)GetValue(XProperty); }
        set { SetValue(XProperty, value); }
    }
    public static readonly DependencyProperty XProperty =
        DependencyProperty.Register("X", typeof(double), typeof(PositionBehavior), new FrameworkPropertyMetadata(0.0,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public double Y
    {
        get { return (double)GetValue(YProperty); }
        set { SetValue(YProperty, value); }
    }
    public static readonly DependencyProperty YProperty =
        DependencyProperty.Register("Y", typeof(double), typeof(PositionBehavior), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));


    protected override void OnAttached()
    {
        AssociatedObject.MouseMove += AssociatedObject_MouseMove;
    }

    private void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
    {
        var pos = e.GetPosition(this.AssociatedObject);
        X = pos.X;
        Y = pos.Y;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
    }
}
  1. VM
class ViewModel1 : INotifyPropertyChanged
{
    private double x;
    private double y;
    public double X
    {
        get { return x; }
        set
        {
            x = value;
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("X"));
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Position"));
        }
    }
    public double Y
    {
        get { return y; }
        set
        {
            y = value;
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Y"));
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Position"));
        }
    }

    public string Position
    {
        get { return $"坐标为:{X:F2}{Y:F2}"; }
    }
    public event PropertyChangedEventHandler? PropertyChanged;
}
  1. View
<Window
    ......
    xmlns:i="http://schemas.microsoft.com/xaml/behaviors">
    <!--双向模式绑定VM中的X,Y-->
    <i:Interaction.Behaviors>
        <local:PositionBehavior X="{Binding X}" Y="{Binding Y}"/>
    </i:Interaction.Behaviors>
    <StackPanel Orientation="Vertical">
        <TextBox x:Name="tbx" FontSize="30" Text="{Binding Position,Mode=OneWay}" />
    </StackPanel>
</Window>

12

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/697721.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【3Ds Max】使用捕捉工具、轴约束工具实现点的精准对齐

目录 问题 解决步骤 一、在XYZ轴上都对齐 二、只在一或两个轴上对齐 问题 举个例子&#xff0c;比如我想让如下的两个立方体的顶点对齐&#xff08;在同一位置&#xff08;XYZ轴都对齐&#xff09;&#xff0c;或仅在一个或两个轴上对齐&#xff09;&#xff1a; 主要使…

【PostgreSQL 数据库技术峰会(成都站)】云原生虚拟数仓 PieCloudDB Database 的架构和关键模块实现...

2023年6月17日&#xff0c;中国开源软件推进联盟 PostgreSQL 分会在成都举办了数据库技术峰会。此次峰会以“新机遇、新态势、新发展”为主题&#xff0c;结合当下信创热潮、人工智能等产业变革背景&#xff0c;探讨 PostgreSQL 数据库在这些新机遇下的发展前景。峰会邀请众多行…

PHP 设备管理系统 mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 设备管理系统 是一套完善的WEB设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 视频演示 PHP 设备管理系统 mysql数据库web结构apache 代码下载 https://download.csd…

70、基于51单片机智能手环心率计步温湿度蓝牙APP监控系统设计(程序+原理图+参考论文+开题报告+元器件清单等)

摘 要 计步器是一种颇受欢迎的日常锻炼进度监控器&#xff0c;可以激励人们挑战自己&#xff0c;增强体质&#xff0c;帮助瘦身。早期设计利用加重的机械开关检测步伐&#xff0c;并带有一个简单的计数器。晃动这些装置时&#xff0c;可以听到有一个金属球来回滑动&#xff0c…

Ansible快速上手

使用Ansible-快速上手 ping模块简介&#xff1a; 该模块不使用ICMP ping&#xff0c;而是使用基于python的模块完成。 语法&#xff1a; ansible 主机IP/或在清单中的名称 -m(表示选择模块) ping &#xff08;表示使用ping模块&#xff09;清单文件&#xff1a; [dev] 192.…

【运维工程师学习】安装VMware并创建Centos8虚拟机(保姆级教程)

安装虚拟机&#xff08;VMware&#xff09;保姆级教程&#xff08;附安装包&#xff09; 下载链接安装步骤创建Centos8虚拟机 下载链接 百度网盘链接&#xff1a;https://pan.baidu.com/s/1pWSsCnP_2Yfe7dRCPQitCg 提取码&#xff1a;6666 Centos8下载&#xff1a;https://nex…

0基础学习VR全景平台篇,第51篇:高级功能-自定义菜单

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;高级功能-自定义菜单&#xff01; 功能位置示意 一、本功能将用在哪里&#xff1f; 自定义菜单&#xff0c;是显示在VR漫游作品底部和顶部各种可点击的图标按钮。…

Liunx 安装 Nginx

1.准备Nginx所需依赖 yum install gcc-cyum install -y zlib zlib-develyum install -y pcre pcre-develyum install -y openssl openssl-devel2.下载tar并解压 wget http://nginx.org/download/nginx-1.23.0.tar.gz tar -xvf nginx-1.23.0.tar.gz 3.安装Nginx cd nginx-1.2…

mmdetection1.4训练fasterrcnn

mmdetection1.4训练fasterrcnn 指定参数文件urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)>No such file or directory: data/coco/annotations/instances…

【C/C++实现进程间通信 一】共享内存方式

前情回顾&#xff1a; 上一期已经讲解过了进程的相关概念以及进程间通信的实现原理&#xff0c;下面仅展示相关代码。 思路&#xff1a; /* 本项目主要用于对同主机上以共享内存方式进行进程间通信的测试 。 1.包含一个外部程序 publisherDemo.exe 以及 subscriberDemo.exe。…

Selenium 使用已开启的浏览器执行测试

实际测试工作中可能遇到某些需要使用手动开启浏览器执行测试的情况&#xff0c;比如某些网站登录需要手机短信验证&#xff0c;为了跳过这步&#xff0c;可以手动登录网站&#xff0c;在已登录的页面继续测试 1、找到本地安装的浏览器启动路径&#xff0c;例如Chrome C:\Progra…

无锡斑目信息技术有限公司与无锡漫途科技有限公司签署战略伙伴合作协议!

2023年6月21日无锡斑目信息技术有限公司与无锡漫途科技有限公司签署战略伙伴合作协议。双方将在数字工厂、智慧城市等领域凭借各自的优势进行全方面的合作。 漫途传感科技总经理田吉成、无锡艾森汇智科技总经理钱小伟、无锡数字城市建设发展工业互联网事业部部长王威共同参加签…

注解实现防止重复提交(Aop)

一、前言 书接上回&#xff0c;上次实现了springboot整合redis&#xff0c;在使用过程中就避免不了重复提交的场景。springboot整合redis_crazyK.的博客-CSDN博客 重复提交的场景&#xff1a; 用于用户误操作&#xff0c;多次点击表单提交按钮由于网速等原因造成页面卡顿&am…

软考高级架构师笔记-8软件工程

目录 1. 前言 & 考情分析2. 软件工程概述3. 能力成熟度模型4. 软件过程模型4.1 敏捷模型4.2 统一过程模型(RUP)5. 逆向工程6. 需求工程7. 系统设计8. 测试基础知识9. 系统运行与维护10. 净室软件工程11. 结语1. 前言 & 考情分析 前文回顾: 软考高级架构师笔记-1计算机…

C++—指针与引用的区别与联系

一、为什么要有引用&#xff08;C语言没有&#xff09; ▪ 因为引⽤和值有⼀样的语义&#xff0c;而指针不是 ▪ 不存在空引⽤&#xff0c;必须初始化&#xff1b;保证值不变&#xff0c;保证编译器更加安全 ▪ 加减号、赋值操作符&#xff0c;作⽤在引用上会触发对象的操作符重…

PHP 人才信息与招聘系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 人才信息与招聘系统 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为PHP APACHE&#xff0c;数据 库为mysql5.0&#xff0c;使用php语言开发。…

Qt笔记-自定义QSet,QHash的Key

官方文档已经说得很详细了。 If you want to use other types as the key, make sure that you provide operator() and a qHash() implementation. Example:#ifndef EMPLOYEE_H#define EMPLOYEE_Hclass Employee{public:Employee() {}Employee(const QString &name, con…

在 Linux 中配置 IPv4 和 IPv6 地址详解

概要 IPv4和IPv6是Internet上常用的两种IP地址协议。在Linux系统中&#xff0c;您可以通过配置网络接口来设置IPv4和IPv6地址。本文将详细介绍如何在Linux中配置IPv4和IPv6地址。 步骤 1&#xff1a;确定网络接口 在开始配置IP地址之前&#xff0c;您需要确定要配置的网络接口…

CSDN竞赛第59期-参赛体验

CSDN竞赛第59期-参赛体验 前言介绍 体验收获反馈准备认可最后 前言 博主空空star主页空空star的主页 大家好&#xff0c;我是空空star&#xff0c;本篇给大家分享一下《CSDN竞赛第59期-参赛体验》。 介绍 CSDN竞赛 体验 我报名参加了CSDN举办的一场编程比赛&#xff0c;这是…

MacOS 升级golang版本后无法debug,升级delve版本

golang版本升级到1.20以后导致debug失效了&#xff0c;本文针对MacOS系统&#xff0c;win系统也可作参考。 WARNING: undefined behavior - version of Delve is too old for Go version 1.20.4 (maximum supported version 1.19) 1、升级delve版本 brew install delve 安装…