diff --git a/AvaloniaBehaviors.sln b/AvaloniaBehaviors.sln
index 0b7c9b4b..cf4f72f9 100644
--- a/AvaloniaBehaviors.sln
+++ b/AvaloniaBehaviors.sln
@@ -79,12 +79,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Xaml.Interactions.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Xaml.Interactions.DragAndDrop", "src\Avalonia.Xaml.Interactions.DragAndDrop\Avalonia.Xaml.Interactions.DragAndDrop.csproj", "{EF243B1A-FF29-41E9-B44B-2E55A73F6CCE}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Xaml.Interactions.Reactive", "src\Avalonia.Xaml.Interactions.Reactive\Avalonia.Xaml.Interactions.Reactive.csproj", "{D647E09E-BBF2-4432-A4E0-80FBB921C1EE}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Xaml.Interactions.Custom", "src\Avalonia.Xaml.Interactions.Custom\Avalonia.Xaml.Interactions.Custom.csproj", "{D647E09E-BBF2-4432-A4E0-80FBB921C1EE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Xaml.Interactions.Events", "src\Avalonia.Xaml.Interactions.Events\Avalonia.Xaml.Interactions.Events.csproj", "{648FFF6A-A8F5-491C-AC1C-19FC2061D6B4}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Xaml.Interactions.Custom", "src\Avalonia.Xaml.Interactions.Custom\Avalonia.Xaml.Interactions.Custom.csproj", "{0BB3669E-45E4-41E8-B765-7F4A5201C4E0}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -147,10 +145,6 @@ Global
{648FFF6A-A8F5-491C-AC1C-19FC2061D6B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{648FFF6A-A8F5-491C-AC1C-19FC2061D6B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{648FFF6A-A8F5-491C-AC1C-19FC2061D6B4}.Release|Any CPU.Build.0 = Release|Any CPU
- {0BB3669E-45E4-41E8-B765-7F4A5201C4E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0BB3669E-45E4-41E8-B765-7F4A5201C4E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0BB3669E-45E4-41E8-B765-7F4A5201C4E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0BB3669E-45E4-41E8-B765-7F4A5201C4E0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -174,7 +168,6 @@ Global
{EF243B1A-FF29-41E9-B44B-2E55A73F6CCE} = {84224365-32B6-46AF-85A2-45640E6D7EEB}
{D647E09E-BBF2-4432-A4E0-80FBB921C1EE} = {84224365-32B6-46AF-85A2-45640E6D7EEB}
{648FFF6A-A8F5-491C-AC1C-19FC2061D6B4} = {84224365-32B6-46AF-85A2-45640E6D7EEB}
- {0BB3669E-45E4-41E8-B765-7F4A5201C4E0} = {84224365-32B6-46AF-85A2-45640E6D7EEB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E64CD420-15B1-487C-9806-41EBE6DC15A4}
diff --git a/Directory.Build.props b/Directory.Build.props
index 91799241..52fc3feb 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,15 +1,16 @@
- 11.0.5
+ 11.0.10.2
Wiesław Šoltés
Wiesław Šoltés
- Copyright © Wiesław Šoltés 2023
+ Copyright © Wiesław Šoltés 2024
MIT
https://github.com/wieslawsoltes/AvaloniaBehaviors
latest
latest
+ true
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 6892fa9c..84e57556 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -14,8 +14,7 @@
-
-
+
diff --git a/samples/BehaviorsTestApplication/BehaviorsTestApplication.csproj b/samples/BehaviorsTestApplication/BehaviorsTestApplication.csproj
index 5a40a07d..00f0a20e 100644
--- a/samples/BehaviorsTestApplication/BehaviorsTestApplication.csproj
+++ b/samples/BehaviorsTestApplication/BehaviorsTestApplication.csproj
@@ -15,7 +15,6 @@
-
@@ -26,7 +25,6 @@
-
diff --git a/samples/BehaviorsTestApplication/ViewModels/ItemViewModel.cs b/samples/BehaviorsTestApplication/ViewModels/ItemViewModel.cs
index 4e19002b..a4336efa 100644
--- a/samples/BehaviorsTestApplication/ViewModels/ItemViewModel.cs
+++ b/samples/BehaviorsTestApplication/ViewModels/ItemViewModel.cs
@@ -4,15 +4,14 @@
namespace BehaviorsTestApplication.ViewModels;
-public class ItemViewModel : ViewModelBase
+public class ItemViewModel(string name) : ViewModelBase
{
- private string _name;
private ObservableCollection? _items;
public string Name
{
- get => _name;
- set => this.RaiseAndSetIfChanged(ref _name, value);
+ get => name;
+ set => this.RaiseAndSetIfChanged(ref name, value);
}
public ObservableCollection? Items
@@ -21,10 +20,5 @@ public ObservableCollection? Items
set => this.RaiseAndSetIfChanged(ref _items, value);
}
- public ItemViewModel(string name)
- {
- _name = name;
- }
-
- public override string ToString() => _name;
+ public override string ToString() => name;
}
\ No newline at end of file
diff --git a/samples/Directory.Packages.props b/samples/Directory.Packages.props
index 26c7d182..15e650f6 100644
--- a/samples/Directory.Packages.props
+++ b/samples/Directory.Packages.props
@@ -1,7 +1,7 @@
true
- 11.0.5
+ 11.0.10
@@ -15,7 +15,6 @@
-
-
+
diff --git a/samples/DragAndDropSample/Behaviors/NodesTreeViewDropHandler.cs b/samples/DragAndDropSample/Behaviors/NodesTreeViewDropHandler.cs
index 25f20c76..e2598014 100644
--- a/samples/DragAndDropSample/Behaviors/NodesTreeViewDropHandler.cs
+++ b/samples/DragAndDropSample/Behaviors/NodesTreeViewDropHandler.cs
@@ -20,10 +20,10 @@ private bool Validate(TreeView treeView, DragEventArgs e, object? sourceConte
var sourceParent = sourceNode.Parent;
var targetParent = targetNode.Parent;
- var sourceNodes = sourceParent is { } ? sourceParent.Nodes : vm.Nodes;
- var targetNodes = targetParent is { } ? targetParent.Nodes : vm.Nodes;
+ var sourceNodes = sourceParent is not null ? sourceParent.Nodes : vm.Nodes;
+ var targetNodes = targetParent is not null ? targetParent.Nodes : vm.Nodes;
- if (sourceNodes is { } && targetNodes is { })
+ if (sourceNodes is not null && targetNodes is not null)
{
var sourceIndex = sourceNodes.IndexOf(sourceNode);
var targetIndex = targetNodes.IndexOf(targetNode);
diff --git a/samples/DragAndDropSample/DragAndDropSample.csproj b/samples/DragAndDropSample/DragAndDropSample.csproj
index 224d9204..ae9dd2e0 100644
--- a/samples/DragAndDropSample/DragAndDropSample.csproj
+++ b/samples/DragAndDropSample/DragAndDropSample.csproj
@@ -20,7 +20,6 @@
-
diff --git a/samples/DraggableDemo/DraggableDemo.csproj b/samples/DraggableDemo/DraggableDemo.csproj
index 5d87ce40..449be893 100644
--- a/samples/DraggableDemo/DraggableDemo.csproj
+++ b/samples/DraggableDemo/DraggableDemo.csproj
@@ -19,7 +19,6 @@
-
diff --git a/src/Avalonia.Xaml.Behaviors/Avalonia.Xaml.Behaviors.csproj b/src/Avalonia.Xaml.Behaviors/Avalonia.Xaml.Behaviors.csproj
index 8aedd2f8..1d620f86 100644
--- a/src/Avalonia.Xaml.Behaviors/Avalonia.Xaml.Behaviors.csproj
+++ b/src/Avalonia.Xaml.Behaviors/Avalonia.Xaml.Behaviors.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netstandard2.1;net461;net6.0;net8.0
+ netstandard2.0;net6.0;net8.0
False
enable
$(NoWarn);NU5128
@@ -15,7 +15,6 @@
-
@@ -28,7 +27,6 @@
-
diff --git a/src/Avalonia.Xaml.Interactions.Custom/AddClassAction.cs b/src/Avalonia.Xaml.Interactions.Custom/AddClassAction.cs
index ac533cdc..46145093 100644
--- a/src/Avalonia.Xaml.Interactions.Custom/AddClassAction.cs
+++ b/src/Avalonia.Xaml.Interactions.Custom/AddClassAction.cs
@@ -62,7 +62,7 @@ public bool RemoveIfExists
/// True if the class is successfully added; else false.
public object Execute(object? sender, object? parameter)
{
- var target = GetValue(StyledElementProperty) is { } ? StyledElement : sender as StyledElement;
+ var target = GetValue(StyledElementProperty) is not null ? StyledElement : sender as StyledElement;
if (target is null || string.IsNullOrEmpty(ClassName))
{
return false;
diff --git a/src/Avalonia.Xaml.Interactions.Reactive/AttachedToVisualTreeBehavior.cs b/src/Avalonia.Xaml.Interactions.Custom/AttachedToVisualTreeBehavior.cs
similarity index 100%
rename from src/Avalonia.Xaml.Interactions.Reactive/AttachedToVisualTreeBehavior.cs
rename to src/Avalonia.Xaml.Interactions.Custom/AttachedToVisualTreeBehavior.cs
diff --git a/src/Avalonia.Xaml.Interactions.Custom/Avalonia.Xaml.Interactions.Custom.csproj b/src/Avalonia.Xaml.Interactions.Custom/Avalonia.Xaml.Interactions.Custom.csproj
index 27e1cb73..7bc10841 100644
--- a/src/Avalonia.Xaml.Interactions.Custom/Avalonia.Xaml.Interactions.Custom.csproj
+++ b/src/Avalonia.Xaml.Interactions.Custom/Avalonia.Xaml.Interactions.Custom.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netstandard2.1;net461;net6.0;net8.0
+ netstandard2.0;net6.0;net8.0
Library
bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml
enable
@@ -15,7 +15,7 @@
-
+
diff --git a/src/Avalonia.Xaml.Interactions.Custom/BindTagToVisualRootDataContextBehavior.cs b/src/Avalonia.Xaml.Interactions.Custom/BindTagToVisualRootDataContextBehavior.cs
index f4389a86..095bcdc8 100644
--- a/src/Avalonia.Xaml.Interactions.Custom/BindTagToVisualRootDataContextBehavior.cs
+++ b/src/Avalonia.Xaml.Interactions.Custom/BindTagToVisualRootDataContextBehavior.cs
@@ -16,7 +16,7 @@ public class BindTagToVisualRootDataContextBehavior : Behavior
protected override void OnAttachedToVisualTree()
{
var visualRoot = (Control?)AssociatedObject?.GetVisualRoot();
- if (visualRoot is { })
+ if (visualRoot is not null)
{
_disposable = BindDataContextToTag(visualRoot, AssociatedObject);
}
@@ -37,6 +37,6 @@ protected override void OnDetachedFromVisualTree()
throw new ArgumentNullException(nameof(target));
var data = source.GetObservable(StyledElement.DataContextProperty);
- return data is { } ? target.Bind(Control.TagProperty, data) : null;
+ return data is not null ? target.Bind(Control.TagProperty, data) : null;
}
}
diff --git a/src/Avalonia.Xaml.Interactions.Custom/BoundsObserverBehavior.cs b/src/Avalonia.Xaml.Interactions.Custom/BoundsObserverBehavior.cs
new file mode 100644
index 00000000..7dab95d4
--- /dev/null
+++ b/src/Avalonia.Xaml.Interactions.Custom/BoundsObserverBehavior.cs
@@ -0,0 +1,76 @@
+using System.Reactive;
+using System.Reactive.Disposables;
+using Avalonia.Controls;
+using Avalonia.Data;
+
+namespace Avalonia.Xaml.Interactions.Custom;
+
+///
+/// Observes the bounds of an associated and updates its Width and Height properties.
+///
+public class BoundsObserverBehavior : DisposingBehavior
+{
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty BoundsProperty =
+ AvaloniaProperty.Register(nameof(Bounds), defaultBindingMode: BindingMode.OneWay);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty WidthProperty =
+ AvaloniaProperty.Register(nameof(Width),
+ defaultBindingMode: BindingMode.TwoWay);
+
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty HeightProperty =
+ AvaloniaProperty.Register(nameof(Height),
+ defaultBindingMode: BindingMode.TwoWay);
+
+ ///
+ /// Gets or sets the bounds of the associated control. This is a styled Avalonia property.
+ ///
+ public Rect Bounds
+ {
+ get => GetValue(BoundsProperty);
+ set => SetValue(BoundsProperty, value);
+ }
+
+ ///
+ /// Gets or sets the width of the associated control. This is a two-way bound Avalonia property.
+ ///
+ public double Width
+ {
+ get => GetValue(WidthProperty);
+ set => SetValue(WidthProperty, value);
+ }
+
+ ///
+ /// Gets or sets the height of the associated control. This is a two-way bound Avalonia property.
+ ///
+ public double Height
+ {
+ get => GetValue(HeightProperty);
+ set => SetValue(HeightProperty, value);
+ }
+
+ ///
+ /// Attaches the behavior to the associated control and starts observing its bounds to update the Width and Height properties accordingly.
+ ///
+ /// A composite disposable used to manage the lifecycle of subscriptions and other disposables.
+ protected override void OnAttached(CompositeDisposable disposables)
+ {
+ if (AssociatedObject is not null)
+ {
+ disposables.Add(this.GetObservable(BoundsProperty)
+ .Subscribe(new AnonymousObserver(bounds =>
+ {
+ Width = bounds.Width;
+ Height = bounds.Height;
+ })));
+ }
+ }
+}
diff --git a/src/Avalonia.Xaml.Interactions.Custom/ButtonClickEventTriggerBehavior.cs b/src/Avalonia.Xaml.Interactions.Custom/ButtonClickEventTriggerBehavior.cs
index 157f0837..e30a1368 100644
--- a/src/Avalonia.Xaml.Interactions.Custom/ButtonClickEventTriggerBehavior.cs
+++ b/src/Avalonia.Xaml.Interactions.Custom/ButtonClickEventTriggerBehavior.cs
@@ -30,7 +30,7 @@ public KeyModifiers KeyModifiers
///
protected override void OnAttachedToVisualTree()
{
- if (AssociatedObject is { })
+ if (AssociatedObject is not null)
{
AssociatedObject.Click += AssociatedObject_OnClick;
AssociatedObject.AddHandler(InputElement.KeyDownEvent, Button_OnKeyDown, RoutingStrategies.Tunnel);
@@ -41,7 +41,7 @@ protected override void OnAttachedToVisualTree()
///
protected override void OnDetachedFromVisualTree()
{
- if (AssociatedObject is { })
+ if (AssociatedObject is not null)
{
AssociatedObject.Click -= AssociatedObject_OnClick;
AssociatedObject.RemoveHandler(InputElement.KeyDownEvent, Button_OnKeyDown);
@@ -51,7 +51,7 @@ protected override void OnDetachedFromVisualTree()
private void AssociatedObject_OnClick(object? sender, RoutedEventArgs e)
{
- if (AssociatedObject is { } && KeyModifiers == _savedKeyModifiers)
+ if (AssociatedObject is not null && KeyModifiers == _savedKeyModifiers)
{
Interaction.ExecuteActions(AssociatedObject, Actions, e);
}
diff --git a/src/Avalonia.Xaml.Interactions.Custom/ButtonExecuteCommandOnKeyDownBehavior.cs b/src/Avalonia.Xaml.Interactions.Custom/ButtonExecuteCommandOnKeyDownBehavior.cs
new file mode 100644
index 00000000..3b1d161a
--- /dev/null
+++ b/src/Avalonia.Xaml.Interactions.Custom/ButtonExecuteCommandOnKeyDownBehavior.cs
@@ -0,0 +1,80 @@
+using System.Reactive.Disposables;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Avalonia.VisualTree;
+
+namespace Avalonia.Xaml.Interactions.Custom;
+
+///
+///
+///
+public class ButtonExecuteCommandOnKeyDownBehavior : AttachedToVisualTreeBehavior