WPF中文网

什么是行为?

在WPF中,假如我们需要给Button增加阴影效果,同时又需要给TextBlock增加阴影效果,或者又来了新的需求,连DataGrid也需要增加阴影效果。虽然我们已经学过如何给一个控件增加阴影效果,那就是在UIElement基类中去设置Effect属性,但是,每个控件都要单独去实现一次阴影效果,未免太繁琐。那又该如何偷懒呢?Behavior类(行为)就是专门用来实现这类需求的。

一句话,行为就是某些控件的共同特征的实现。如上所示,既然所有控件都有Effect属性,那干脆将这个特征写成一个行为,哪个控件有这个需求,直接调用这个行为即可。说是调用行为,专业点说,是将这个行业附加到某个控件上。

一、行为基类的定义

首先,我们来看一下Behavior基类的定义,了解大致组成后,我们才知道要怎么使用它。

namespace System.Windows.Interactivity
{
    public abstract class Behavior : Animatable, IAttachedObject
    {
        protected Type AssociatedType { get; }
        protected DependencyObject AssociatedObject { get; }

        public void Attach(DependencyObject dependencyObject);
        public void Detach();
        protected override Freezable CreateInstanceCore();
        protected virtual void OnAttached();
        protected virtual void OnDetaching();
    }
}

从定义上看,第一,它是一个抽象类,所以我们不能直接使用它,而是去继承它,在子类中实现我们自己的行业效果。第二,它继承于Animatable,说明行为是可以动画实现的。第三,它的命名空间为System.Windows.Interactivity,这个空间在哪里?

要使用行为,我们需要引入一个.dll动态库,或者您可以在nuget上找到它。请安装Microsoft.Xaml.Behaviors.Wpf这个组件包。

Behavior泛型基类

namespace System.Windows.Interactivity
{
    public abstract class Behavior<T> : Behavior where T : DependencyObject
    {
        protected Behavior();

        protected T AssociatedObject { get; }
    }
}

其实,我们实际继承的是行为的泛型基类,因为WPF并不知道我们要给哪一种控件定义行为,于是,干脆提供一个泛型基类供我们使用。所以,我们将两个基类合并起来介绍。

AssociatedObject属性:这个属性通常表示一个控件,类型是DependencyObject(依赖对象),也就是说,我们写的行为要给某个控件使用的前提是,这个控件是一个DependencyObject(依赖对象)。

OnAttached():这是一个虚方法,将来在行为中被重写,表示附加一个行为时要执行的业务逻辑。

OnDetaching():这是一个虚方法,将来在行为中被重写,表示分离一个行为时要执行的业务逻辑。

二、行为的开发

接下来,我们假如要给一个TextBlock文字块增加一个阴影效果。那么,就可以编写一个自定义行为TextBehavior,相关代码如下:

public class TextBehavior : Behavior<TextBlock>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.MouseEnter += AssociatedObject_MouseEnter;
        AssociatedObject.MouseLeave += AssociatedObject_MouseLeave;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter;
        AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave;
    }

    private void AssociatedObject_MouseEnter(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        var element = sender as TextBlock;
        DropShadowEffect effect = new DropShadowEffect();
        effect.Color = Colors.Gold;
        effect.ShadowDepth = 0;
        effect.BlurRadius = 15;
        element.Effect = effect;            
    }

    private void AssociatedObject_MouseLeave(object sender, 
        System.Windows.Input.MouseEventArgs e)
    {
        var element = sender as TextBlock;
        DropShadowEffect effect = new DropShadowEffect();
        effect.Color = Colors.Gold;
        effect.ShadowDepth = 0;
        effect.BlurRadius = 15;
        element.Effect = null;
    }
}

在上面的代码中, 我们给AssociatedObject的MouseEnter和MouseLeave分别订阅了两个事件回调函数,在回调函数中去设置DropShadowEffect 效果。注意,这里的AssociatedObject实际上就等于TextBlock控件哦。

在定义好一个行为后,接下来就是在XAML中使用它。

第一步,在XAML中导入命名空间 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

第二步,编写前端XAML代码,引用TextBehavior行为,完整代码如下:

<Window x:Class="HelloWorld.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:HelloWorld" 
        xmlns:controls="clr-namespace:HelloWorld.Controls"
        xmlns:helper="clr-namespace:HelloWorld.MVVM" 
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 
        xmlns:behavior="clr-namespace:HelloWorld.Behaviors"
        mc:Ignorable="d" Background="DarkCyan"
        Title="WPF中文网 - 行为 - www.wpfsoft.com" Height="350" Width="500">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Canvas>
        <TextBlock Text="WPF中文网" 
                   Foreground="White" 
                   FontSize="60" 
                   Canvas.Left="92" 
                   Canvas.Top="75">
            <i:Interaction.Behaviors>
                <behavior:TextBehavior/>
            </i:Interaction.Behaviors>
        </TextBlock>
        <TextBlock Text="Behavior行为之阴影效果" 
                   Foreground="White" 
                   FontSize="40" 
                   Canvas.Left="21" 
                   Canvas.Top="182">
            <i:Interaction.Behaviors>
                <behavior:TextBehavior/>
            </i:Interaction.Behaviors>
        </TextBlock>
    </Canvas>
</Window>

最后,运行调试,鼠标移上去,文字将增加阴影,鼠标移开,文字阴影将消失。

当前课程源码下载:(注明:本站所有源代码请按标题搜索)

文件名:106-《什么是行为》-源代码
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff

——重庆教主 2023年11月21日

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1