目录

Behavior

在WPF中,Behavior是对一种将逻辑封装成可复用组件的技术,它的核心思想是:”不修改控件的代码,却能改变控件的行为“。它是对”命令(Command)“和"事件(Event)“的有力补充,特别是在处理一些纯UI交互逻辑(如:限制输入,窗口拖拽,动画触发)时非常优雅。

什么是Behavior?

Behavior 属于 XAML Behavior for WPF库(原来叫 Blend Interactivity)

  • 本质:是一个挂载在控件上的”外挂插件“。
  • 解耦:它可以让你把复杂的C#交互逻辑从 MainWindow.xaml.cs(后台代码)中提取出来,变成一个可以在不同项目中重复使用的类。
  • 原理:它通过 OnAttached() 方法获得对控件的引用,然后通过监听该控件的事件来实现功能。

安装NuGet包:Microsoft.Xaml.Behaviors.Wpf

demo:制作一个”拖拽窗口“的行为

通常 WPF 的 Window 只有点击标题栏才能拖动。我们写一个 Behavior,让任何放置在窗口里的控件(比如一个Border或Image)都能通过鼠标左键按住来拖动整个窗口。

 // 泛型 T 约束这个行为只能给 Window 或其子类使用
 public class DragWindowBehavior : Behavior<FrameworkElement>
 {
     // 当行为被附加到控件时才触发
     protected override void OnAttached()
     {
         base.OnAttached();

         // 为关联的控件注册鼠标左键按下事件
         this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_MoseLeftButtonDown;
     }

     // 当行为从控件移除时触发(防止内存泄露)
     protected override void OnDetaching()
     {
         base.OnDetaching();
         this.AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MoseLeftButtonDown;
     }

     private void AssociatedObject_MoseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     {
         // 获取控件所属的窗口
         Window window = Window.GetWindow(this.AssociatedObject);

         if (window != null) 
         {
             // 调用系统内置的拖动方法
             window.DragMove();
         }
     }
 }
<Window
    x:Class="BehaviorDemo.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:i="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:local="clr-namespace:BehaviorDemo"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="400"
    Height="300"
    AllowsTransparency="True"
    Background="Transparent"
    WindowStyle="None"
    mc:Ignorable="d">
    <Grid Background="White">
        <Border
            Height="50"
            VerticalAlignment="Top"
            Background="#333333">
            <i:Interaction.Behaviors>
                <local:DragWindowBehavior />
            </i:Interaction.Behaviors>

            <TextBlock
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Foreground="White"
                Text="按住这里拖动窗口" />
        </Border>

        <Button Content="关闭窗口" VerticalAlignment="Bottom" Margin="20"
                Click="Button_Click"/>
    </Grid>
</Window>

核心API:

  • Behavior 行为的基类。T 是你希望此行为应用的控件类型(如 Button, TextBox 或 FrameworkElement)。
  • AssociatedObject 这是行为内部最重要的属性。它代表了当前行为被“挂载”在哪一个具体的控件实例上。
  • OnAttached() 钩子方法。当 XAML 加载并把行为绑定到控件时调用。在这里注册事件(如 MouseDown, Loaded)。
  • OnDetaching() 销毁方法。当控件被卸载或行为被移除时调用。务必在这里注销事件,否则会导致内存无法回收

为什么要用 Behavior 而不是直接写事件?

  • 高复用性: 上面的 DragWindowBehavior 你可以放在任何项目中,只要给控件加上那三行 XAML,它立刻就能拖动窗口,不需要重复写 C# 代码。
  • 保持后台代码简洁: 遵循 MVVM 模式。如果你想在 TextBox 获取焦点时自动全选文字,写成 Behavior 比在每个页面的后台写 OnFocus 事件要干净得多。
  • 设计师友好: 在 Expression Blend 等工具中,设计师可以通过拖拽 Behavior 来实现交互,而不需要触碰 C# 逻辑。