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

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

<BorderWidth="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();}
}
<BorderWidth="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:ChangePropertyActionPropertyName="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

<ButtonWidth="150"Height="100"Content="Button.Triggers"><Button.Triggers><EventTrigger RoutedEvent="MouseEnter"><BeginStoryboard><Storyboard><ColorAnimationStoryboard.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.hqwc.cn/news/4888.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大厂月入3w+,失业焦虑折磨着我

大家好&#xff0c;这里是程序员晚枫&#xff0c;小红书也叫这个名字。 周末和一位老朋友聚会&#xff0c;聊了聊一个很现实的收入问题&#xff0c;巧合的是&#xff1a;他的焦虑&#xff0c;竟然和月薪5k的我一模一样。 今天给大家分享一下。 1、外人看来&#xff0c;让人羡…

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

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

吴恩达ChatGPT《LangChain for LLM Application Development》笔记

基于 LangChain 的 LLM 应用开发 1. 介绍 现在&#xff0c;使用 Prompt 可以快速开发一个应用程序&#xff0c;但是一个应用程序可能需要多次写Prompt&#xff0c;并对 LLM 的输出结果进行解析。因此&#xff0c;需要编写很多胶水代码。 Harrison Chase 创建的 LangChain 框…

初步认识Java垃圾回收算法

GCRoot指被栈上直接或间接引用的对象&#xff0c;或被本地方法栈直接或间接引用的对象&#xff0c;或被方法区引用的对象。 被引用的对象是不能被删除的。 如果对象跟GCRoot并没有直接或间接相连的关系&#xff0c;那么这些对象就可以被删除了。 标记-清理&#xff1a;将需要删…

基于FPGA的RC滤波器设计实现

目录 简介&#xff1a; 传递函数 FPGA代码实现 总结 简介&#xff1a; RC滤波器的特性基本情况介绍 RC一阶低通滤波介绍&#xff1b;RC滤波器电路简单&#xff0c;抗干扰性强&#xff0c;有较好的低频性能&#xff0c;并且选用标准的阻容元件易得&#xff0c;所以在工程测…

GAMES101 笔记 Lecture08 Shading 2(Shading, Pipeline and Texture Mapping)

目录 Specular Term(高光项)Ambient Term(环境光照项)Blinn-Phong Reflection ModelShading Frequencies(着色频率)Shade each triangle(flat shading)在每个三角形上进行着色Shade each vertex (Gouraud shading)(顶点着色)Shade each pixel (Phong shading)Defining Per-Vert…

ES基本操作(JavaAPI篇)

引入jar包依赖 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- es客户端 --><dependency><groupI…

Loadrunner怎么实现MD5加密

目录 前言&#xff1a; 1、写一个md5.h文件&#xff0c;将其放入脚本路径下 2、在globals.h中加入#include “md5.h” 3、在Action中写脚本&#xff0c;脚本示例如下&#xff1a; 前言&#xff1a; 在 LoadRunner 中实现 MD5 加密可以通过使用 LoadRunner 提供的函数来完成…

【FPGA零基础学习之旅#9】状态机基础知识

&#x1f389;欢迎来到FPGA专栏~状态机基础知识 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指正…

macOS Ventura 13.5beta4(22G5059d)发布

系统介绍 黑果魏叔 6 月 28 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.5 开发者预览版 Beta 4 更新&#xff08;内部版本号&#xff1a;22G5059d&#xff09;&#xff0c;本次更新距离上次发布隔了 12 天。 macOS Ventura 带来了台前调度、连续互通相机、F…

TypeScript ~ 掌握基本类型 ②

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; TypeScript ~ TS &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &…

SQL-每日一题【182.查找重复的电子邮箱】

题目 表: Person 编写一个 SQL 查询来报告所有重复的电子邮件。 请注意&#xff0c;可以保证电子邮件字段不为 NULL。 以 任意顺序 返回结果表。 查询结果格式如下例。 示例 1: 解题思路 前置知识 count&#xff08;&#xff09; 1.count(*) &#xff1a;统计所有的行数&a…