![]() |
VOOZH | about |
dotnet add package NuExt.Minimal.Behaviors.Wpf --version 0.7.3
NuGet\Install-Package NuExt.Minimal.Behaviors.Wpf -Version 0.7.3
<PackageReference Include="NuExt.Minimal.Behaviors.Wpf" Version="0.7.3" />
<PackageVersion Include="NuExt.Minimal.Behaviors.Wpf" Version="0.7.3" />Directory.Packages.props
<PackageReference Include="NuExt.Minimal.Behaviors.Wpf" />Project file
paket add NuExt.Minimal.Behaviors.Wpf --version 0.7.3
#r "nuget: NuExt.Minimal.Behaviors.Wpf, 0.7.3"
#:package NuExt.Minimal.Behaviors.Wpf@0.7.3
#addin nuget:?package=NuExt.Minimal.Behaviors.Wpf&version=0.7.3Install as a Cake Addin
#tool nuget:?package=NuExt.Minimal.Behaviors.Wpf&version=0.7.3Install as a Cake Tool
NuExt.Minimal.Behaviors.Wpf is a minimalistic, production‑ready implementation of WPF Attached Behaviors for MVVM. It delivers deterministic, predictable interactivity with ready‑to‑use behaviors (EventToCommand, KeyToCommand) and template‑driven composition — dynamic behavior injection via BehaviorsTemplate and runtime selection via BehaviorsTemplateSelector.
👁 NuGet
👁 Build
👁 License
👁 Downloads
Package ecosystem: The core package ships the foundational attached behavior infrastructure and essential behaviors for MVVM. For extra behaviors/services, see NuExt.Minimal.Mvvm.Wpf.
BehaviorsTemplate and BehaviorsTemplateSelector let you define and reuse behavior sets with minimal XAML.Interaction – attached properties: Behaviors, BehaviorsTemplate, BehaviorsTemplateSelector, BehaviorsTemplateSelectorParameter.BehaviorCollection – observable collection managing behavior lifecycle.EventToCommand, KeyToCommand – ready-to-use behaviors with a predictable contract.
<nx:Interaction.Behaviors>
<nx:EventToCommand EventName="Loaded" Command="{Binding LoadedCommand}" />
<nx:KeyToCommand Gesture="Ctrl+S" Command="{Binding SaveCommand}" />
<local:MyService />
</nx:Interaction.Behaviors>
xmlns:nx="http://schemas.nuext.minimal/xaml"
<Button Content="Click Me">
<nx:Interaction.Behaviors>
<nx:EventToCommand EventName="Click" Command="{Binding MyCommand}" />
</nx:Interaction.Behaviors>
</Button>
Define once, apply many times. The template supports two concise formats:
ContentControl.ContentItemsControl.Items<Window.Resources>
<DataTemplate x:Key="SaveBehavior">
<ContentControl>
<nx:KeyToCommand Gesture="Ctrl+S" Command="{Binding SaveCommand}" />
</ContentControl>
</DataTemplate>
</Window.Resources>
<TextBox nx:Interaction.BehaviorsTemplate="{StaticResource SaveBehavior}" />
<Window.Resources>
<DataTemplate x:Key="EditBehaviors">
<ItemsControl>
<nx:KeyToCommand Gesture="F2" Command="{Binding StartEditCommand}" />
<nx:KeyToCommand Gesture="Ctrl+S" Command="{Binding SaveCommand}" />
<nx:KeyToCommand Gesture="Escape" Command="{Binding CancelCommand}" />
</ItemsControl>
</DataTemplate>
</Window.Resources>
<ListBox nx:Interaction.BehaviorsTemplate="{StaticResource EditBehaviors}" />
Switch behavior sets at runtime:
<Window.Resources>
<DataTemplate x:Key="ReadOnlyTemplate">
<ContentControl>
<nx:KeyToCommand Gesture="F2" Command="{Binding StartEditCommand}" />
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="EditableTemplate">
<ItemsControl>
<nx:KeyToCommand Gesture="Ctrl+S" Command="{Binding SaveCommand}" />
<nx:KeyToCommand Gesture="Escape" Command="{Binding CancelCommand}" />
</ItemsControl>
</DataTemplate>
<local:MyBehaviorSelector x:Key="BehaviorSelector"
ReadOnlyTemplate="{StaticResource ReadOnlyTemplate}"
EditableTemplate="{StaticResource EditableTemplate}" />
</Window.Resources>
<TextBox nx:Interaction.BehaviorsTemplateSelector="{StaticResource BehaviorSelector}" />
public sealed class MyBehaviorSelector : DataTemplateSelector
{
public DataTemplate? ReadOnlyTemplate { get; set; }
public DataTemplate? EditableTemplate { get; set; }
public override DataTemplate? SelectTemplate(object? item, DependencyObject container)
=> (item is MyDataItem m && m.IsReadOnly) ? ReadOnlyTemplate : EditableTemplate;
}
Tip: If no selector parameter is provided, the framework resolves the element’s data item (DataContext, Content, or Header). Bind
BehaviorsTemplateSelectorParameter="{Binding}"to drive selection from theDataContextexplicitly when needed.
<nx:EventToCommand EventName="Loaded" Command="{Binding InitializeCommand}" />
<ListView>
<nx:Interaction.Behaviors>
<nx:EventToCommand EventName="SelectionChanged"
Command="{Binding SelectionChangedCommand}"
PassEventArgsToCommand="True" />
</nx:Interaction.Behaviors>
</ListView>
<TextBox>
<nx:Interaction.Behaviors>
<nx:KeyToCommand Gesture="Ctrl+Enter" Command="{Binding SubmitCommand}" />
<nx:KeyToCommand Gesture="Escape" Command="{Binding CancelCommand}" />
</nx:Interaction.Behaviors>
</TextBox>
<TextBox nx:Interaction.BehaviorsTemplateSelector="{StaticResource BehaviorSelector}"
nx:Interaction.BehaviorsTemplateSelectorParameter="{Binding}" />
<nx:EventToCommand EventName="PreviewMouseDown" ProcessHandledEvent="True"
Command="{Binding PreviewMouseDownCommand}" />
<nx:EventToCommand EventName="SelectionChanged"
Command="{Binding SelectionChangedCommand}"
EventArgsParameterPath="AddedItems[0]" />
A meaningful non‑visual service can participate in nx:Interaction.Behaviors and solve a concrete UX task.
Example below: auto‑scroll the host control to the currently selected item for ListBox/ListView/DataGrid.
AutoScrollSelectedItemService
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
using Minimal.Behaviors.Wpf;
namespace MyApp.Behaviors
{
/// <summary>
/// Automatically scrolls the host selector (ListBox/ListView/DataGrid) to the current SelectedItem.
/// </summary>
public sealed class AutoScrollSelectedItemService : Behavior<Selector>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += OnSelectionChanged;
AssociatedObject.Dispatcher.InvokeAsync(ScrollToCurrent, DispatcherPriority.Loaded);
}
protected override void OnDetaching()
{
AssociatedObject.SelectionChanged -= OnSelectionChanged;
base.OnDetaching();
}
private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
AssociatedObject.Dispatcher.InvokeAsync(ScrollToCurrent, DispatcherPriority.Background);
}
private void ScrollToCurrent()
{
var item = AssociatedObject.SelectedItem;
if (item is null)
return;
// Prefer control-specific ScrollIntoView when available.
switch (AssociatedObject)
{
case ListBox lb:
lb.ScrollIntoView(item);
return;
case ListView lv:
lv.ScrollIntoView(item);
return;
case DataGrid dg:
dg.ScrollIntoView(item);
return;
}
// Fallback: resolve container and bring it into view.
if (AssociatedObject.ItemContainerGenerator.ContainerFromItem(item) is FrameworkElement fe)
fe.BringIntoView();
}
}
}
<Window
x:Class="MyApp.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:nx="http://schemas.nuext.minimal/xaml"
xmlns:local="clr-namespace:MyApp.Behaviors">
<Grid>
<ListView ItemsSource="{Binding Items}"
SelectedItem="{Binding Selected, Mode=TwoWay}">
<nx:Interaction.Behaviors>
<local:AutoScrollSelectedItemService />
</nx:Interaction.Behaviors>
</ListView>
</Grid>
</Window>
OnAttached, unsubscribe in OnDetaching. No dangling handlers.DispatcherPriority.Background or offload to a worker.Dispatcher.nx:Interaction.Behaviors attach top‑to‑bottom; place services before/after others if you need specific ordering.Parameter precedence (short):
CommandParameter (if set) — wins; everything else is ignored.EventArgsConverter (if set):EventArgsParameterPath ? eventArgs[path] : eventArgs)EventArgsConverterParameter ?? sender)EventArgsParameterPath (no converter): eventArgs[path]SenderParameterPath (no converter): sender[path]PassEventArgsToCommand ? eventArgs : nullWhen a converter is set (step 2),
SenderParameterPathis intentionally ignored.
Without a converter, if both paths are provided, step 3 (EventArgsParameterPath) is considered before step 4 (SenderParameterPath).
BehaviorsTemplateSelector and a single parameter binding.ICommand binding with a well-defined parameter precedence.If your project uses Blend Behaviors, System.Windows.Interactivity, or Microsoft.Xaml.Behaviors, migration is straightforward. Minimal.Behaviors preserves the mental model but removes the heavy trigger/action stack.
| Blend / Interactivity | Minimal equivalent | Notes |
|---|---|---|
| Interaction.Behaviors | nx:Interaction.Behaviors | Same structure, predictable lifecycle. |
| EventTrigger + InvokeCommandAction | nx:EventToCommand | Direct event → ICommand binding. |
| KeyBinding / InputBinding | nx:KeyToCommand | Keyboard gestures per control, MVVM-friendly. |
| Reusable stacks in resources | BehaviorsTemplate | Define behavior sets once, attach anywhere. |
| Runtime switching via triggers | BehaviorsTemplateSelector | Cleaner, deterministic selection. |
No hidden dependencies, no extra assemblies, no performance traps. Your existing behavior patterns map directly to smaller, clearer equivalents.
CommandParameter for high-frequency events; avoid deep parameter extraction on high-frequency routes (e.g., mouse move).BehaviorsTemplateSelectorParameter (typically to "{Binding}") to update only when needed.Via NuGet:
dotnet add package NuExt.Minimal.Behaviors.Wpf
Or via Visual Studio:
Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution....NuExt.Minimal.Behaviors.Wpf.Prefer to vendor the framework and keep your app dependency‑flat?
Use the source package to embed the entire behavior infrastructure directly into your project:
This is ideal for teams that prefer zero external runtime dependencies and want to keep UI infrastructure fully in-tree.
NuGet: NuExt.Minimal.Behaviors.Wpf.Sources.
dotnet add package NuExt.Minimal.Behaviors.Wpf.Sources
Or via Visual Studio:
Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution....NuExt.Minimal.Behaviors.Wpf.Sources.Issues and PRs are welcome. Keep changes minimal and performance-conscious.
MIT. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows7.0 net8.0-windows7.0 is compatible. net9.0-windows net9.0-windows was computed. net9.0-windows7.0 net9.0-windows7.0 is compatible. net10.0-windows net10.0-windows was computed. net10.0-windows7.0 net10.0-windows7.0 is compatible. |
| .NET Framework | net462 net462 is compatible. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
Showing the top 1 NuGet packages that depend on NuExt.Minimal.Behaviors.Wpf:
| Package | Downloads |
|---|---|
|
NuExt.Minimal.Mvvm.Wpf
NuExt.Minimal.Mvvm.Wpf is an extension for the lightweight MVVM framework NuExt.Minimal.Mvvm, specifically designed for WPF applications. Commonly Used Types: Minimal.Mvvm.ModelBase Minimal.Mvvm.Wpf.ControlViewModel Minimal.Mvvm.Wpf.DocumentContentViewModelBase Minimal.Mvvm.Wpf.WindowViewModel Minimal.Mvvm.Wpf.IAsyncDialogService Minimal.Mvvm.Wpf.IAsyncDocument Minimal.Mvvm.Wpf.IAsyncDocumentContent Minimal.Mvvm.Wpf.IAsyncDocumentManagerService Minimal.Mvvm.Wpf.InputDialogService Minimal.Mvvm.Wpf.OpenWindowsService Minimal.Mvvm.Wpf.SettingsService Minimal.Mvvm.Wpf.TabbedDocumentService Minimal.Mvvm.Wpf.ViewLocator Minimal.Mvvm.Wpf.WindowedDocumentService Minimal.Mvvm.Wpf.WindowPlacementService |
This package is not used by any popular GitHub repositories.