【WPF】Behavior 行为
前言
行为是一类事物的共同特征,在WPF中通过行为可以封装一些通用的界面功能,从而实现代码重用来提高开发效率。因此他是一个非常好用的工具。行为将事件和处理方法封装到一起,简化ui界面xaml代码的复杂性和复用性。
通常情况下不用自己写行为, 直接使用Behaviors包中的行为就行了。也可以自定义行为。
使用Behaviors包
安装Microsoft.Xaml.Behaviors.Wpf 这个包是XAML Behaviors是作为Blend System.Windows.Interactivity库的一部分提供。
2. 资源引用
<Window x:Class="Login.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:b="http://schemas.microsoft.com/xaml/behaviors" > </Window>
然后将其引入到项目中。
在这里插入图片描述
使用 Behaviors包中的行为
自定义行为--文本框水印
1.创建一个行为类TextBoxWaterMarkBehavior,继承 Behavior<UIElement>,并指定行为覆盖元素类型UIElement。意思是该行为可适用于UIElement下的所有子元素。
using System.Windows; using System.Windows.Interactivity; using System.Windows.Media; using System.Windows.Media.Effects; namespace Deamon { public class TextBoxWaterMarkBehavior: Behavior<UIElement> { } }
2.重写Behavior
里面的两个函数OnAttached(附加后)与OnDetaching(分离时)
/// <summary> /// 文本框水印 行为Demo /// </summary> public class TextBoxWaterMarkBehavior : Behavior<UIElement> { private TextBox? textBox; //文本框 private string isNotNullForeground; //不为空的文本颜色 private string waterMarkText =""; //水印文本 private Brush waterMarkForeground;//水印颜色 public string IsNotNullForeground { set => isNotNullForeground= value; } public string WaterMarkText { set => waterMarkText = value; } /// <summary> /// 最重要重新方法之一必须 +=后双击tab 会补全代码 /// </summary> protected override void OnAttached() { base.OnAttached(); // AssociatedObject 是行为的关联对象,类型为我们指定的FrameworkElement AssociatedObject.LostFocus += AssociatedObject_LostFocus; AssociatedObject.GotFocus += AssociatedObject_GotFocus; } /// <summary> /// 最重要重新方法之一必须 +=后双击tab 会不全代码 /// </summary> protected override void OnDetaching() { base.OnDetaching(); // 移除 AssociatedObject.LostFocus -= AssociatedObject_LostFocus; AssociatedObject.GotFocus -= AssociatedObject_GotFocus; } private void AssociatedObject_GotFocus(object sender, RoutedEventArgs e) { if (AssociatedObject is not null) { textBox = this.AssociatedObject as TextBox; if (textBox != null&&textBox.Text==waterMarkText) { textBox.Text = ""; waterMarkForeground = textBox.Foreground; textBox.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(isNotNullForeground)); } } } private void AssociatedObject_LostFocus(object sender, RoutedEventArgs e) { if (textBox is not null && textBox.Text =="") { textBox.Foreground = waterMarkForeground; textBox.Text = waterMarkText; } else { // textBox.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(textBox.Foreground)); } } }
3.通过AssociatedObject(关联对象:是行为的关联对象,类型为我们指定的UIElement),实现实际行为的触发:文本框获取焦点 。
3.1在OnAttached方法中添加文本框获取/失去焦点响应事件处理方法。输入AssociatedObject.LostFocus +=后双击tab 会补全AssociatedObject_LostFocus;以及对应的处理方法。
3.2在OnDetaching方法中移除文本框获取/失去焦点响应事件处理方法。
4.在鼠标响应事件处理方法中实现行为。
使用行为
<Window x:Class="Deamon.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Deamon" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid>
<!--其他代码--> <TextBox Style="{DynamicResource LoginNameCss}" Foreground="#9999" x:Name="LoginName" VerticalContentAlignment="Center" FontSize="18" Height="40" Margin="20,0,20,0" Padding="10,0,0,0">
<b:Interaction.Behaviors >
<local:TextBoxWaterMarkBehavior WaterMarkText="手机/邮箱" IsNotNullForeground="#000"/>
</b:Interaction.Behaviors> 手机/邮箱</TextBox>
<!--其他代码--> </Grid> </Window>
效果
水印效果还可以通过样式联合控件模板一起实现,详细请看。
总结
行为与触发器有一些共同之处,很多时候可以直接使用触发器来代替,但是在做一些通用的功能时,行为不失为很好的解决方案。