【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>

 

效果

水印效果还可以通过样式联合控件模板一起实现,详细请看。

总结

行为与触发器有一些共同之处,很多时候可以直接使用触发器来代替,但是在做一些通用的功能时,行为不失为很好的解决方案。

 

posted @ 2022-08-15 01:37  小林野夫  阅读(5198)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/