Skill v1.0.1
currentAutomated scan100/100+1 new
version: "1.0.1" description: "Generates WPF Behavior<T> classes using Microsoft.Xaml.Behaviors.Wpf. Use when adding reusable interaction logic to controls, creating drag behaviors, or scaffolding a new Behavior class. Usage: /wpf-dev-pack:make-wpf-behavior <BehaviorName>" argument-hint: [BehaviorName]
WPF Behavior Generator
If `$0` is empty, use the AskUserQuestion tool to ask: "Enter the Behavior name (e.g., SelectAllOnFocus, DragMove)". Do NOT proceed until a valid name is provided. Use the response as the BehaviorName for all subsequent steps.
Generate a $0Behavior class based on Microsoft.Xaml.Behaviors.Wpf.
- Replace
{TargetType}with the appropriate WPF type (e.g., TextBox, UIElement, Window) based on the behavior name and context. - Replace
{Namespace}with the project's root namespace detected from csproj or existing code. - Replace
{Project}with the target project path.
Generated Code
namespace {Namespace}.Behaviors;public sealed class $0Behavior : Behavior<{TargetType}>{#region Dependency Propertiespublic static readonly DependencyProperty IsEnabledProperty =DependencyProperty.Register(nameof(IsEnabled),typeof(bool),typeof($0Behavior),new PropertyMetadata(true));public bool IsEnabled{get => (bool)GetValue(IsEnabledProperty);set => SetValue(IsEnabledProperty, value);}#endregion#region Lifecycleprotected override void OnAttached(){base.OnAttached();AssociatedObject.Loaded += OnLoaded;}protected override void OnDetaching(){base.OnDetaching();AssociatedObject.Loaded -= OnLoaded;}#endregion#region Event Handlersprivate void OnLoaded(object sender, RoutedEventArgs e){if (!IsEnabled){return;}// TODO: Implement behavior logic}#endregion}
XAML Usage
<Window xmlns:b="http://schemas.microsoft.com/xaml/behaviors"xmlns:behaviors="clr-namespace:{Namespace}.Behaviors"><{TargetType}><b:Interaction.Behaviors><behaviors:$0Behavior IsEnabled="{Binding IsBehaviorEnabled}"/></b:Interaction.Behaviors></{TargetType}></Window>
Common Behavior Patterns
Focus Management
public sealed class FocusOnLoadBehavior : Behavior<UIElement>{protected override void OnAttached(){base.OnAttached();AssociatedObject.Loaded += (s, e) => AssociatedObject.Focus();}}
Input Handling
public sealed class EnterKeyBehavior : Behavior<TextBox>{public static readonly DependencyProperty CommandProperty =DependencyProperty.Register(nameof(Command), typeof(ICommand),typeof(EnterKeyBehavior));public ICommand? Command{get => (ICommand?)GetValue(CommandProperty);set => SetValue(CommandProperty, value);}protected override void OnAttached(){base.OnAttached();AssociatedObject.KeyDown += OnKeyDown;}protected override void OnDetaching(){base.OnDetaching();AssociatedObject.KeyDown -= OnKeyDown;}private void OnKeyDown(object sender, KeyEventArgs e){if (e.Key == Key.Enter){Command?.Execute(AssociatedObject.Text);}}}
Required Package
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.*" />
File Location
{Project}/└── Behaviors/└── $0Behavior.cs
Best Practices
| DO | DON'T | |
|---|---|---|
| Unsubscribe events in OnDetaching | Missing event unsubscription (memory leak) | |
| Expose settings via DependencyProperty | Use hardcoded values | |
| Apply IsEnabled pattern | Always execute without condition | |
| Check AssociatedObject for null | Use without null check |
Related
/wpf-dev-pack:make-wpf-chatclientemits two workedBehavior<T>instances
built on this template: an EnterCommandBehavior (Enter=send / Shift+Enter=newline, IME-safe, via PreviewKeyDown with a Command/CommandParameter DP pair) and a StickToBottomBehavior (pin a streaming ScrollViewer to the newest content unless the user scrolled up). See it for a Command-DP behavior and an event-tracking behavior in context.