diff --git a/Directory.Build.props b/Directory.Build.props
index dbffb33ed..c615fd576 100755
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -2,8 +2,17 @@
- 8.0
+ 12.0
enable
+ portable
+ 8.0.21
+
+
+
+
+ XToolkit
+ Softeq Development Corporation
+ Copyright © 2024 Softeq Development Corporation
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 25c1277cb..bfa391608 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2018 Softeq
+Copyright (c) 2024 Softeq
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 40dd0175a..733d6f34b 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,9 @@ Common | [![Softeq.XToolkit.Common](https://buildstats.info/nuget/Softeq.XToo
Bindings | [![Softeq.XToolkit.Bindings](https://buildstats.info/nuget/Softeq.XToolkit.Bindings?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.Bindings)
Permissions | [![Softeq.XToolkit.Permissions](https://buildstats.info/nuget/Softeq.XToolkit.Permissions?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.Permissions)
PushNotifications | [![Softeq.XToolkit.PushNotifications](https://buildstats.info/nuget/Softeq.XToolkit.PushNotifications?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.PushNotifications)
+Remote | [![Softeq.XToolkit.Remote](https://buildstats.info/nuget/Softeq.XToolkit.Remote?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.Remote)
WhiteLabel | [![Softeq.XToolkit.WhiteLabel](https://buildstats.info/nuget/Softeq.XToolkit.WhiteLabel?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.WhiteLabel)
WhiteLabel.Essentials | [![Softeq.XToolkit.WhiteLabel.Essentials](https://buildstats.info/nuget/Softeq.XToolkit.WhiteLabel.Essentials?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.WhiteLabel.Essentials)
-WhiteLabel.Forms | [![Softeq.XToolkit.WhiteLabel.Forms](https://buildstats.info/nuget/Softeq.XToolkit.WhiteLabel.Forms?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.WhiteLabel.Forms)
-Remote | [![Softeq.XToolkit.Remote](https://buildstats.info/nuget/Softeq.XToolkit.Remote?includePreReleases=true)](https://www.nuget.org/packages/Softeq.XToolkit.Remote)
## Documentation
diff --git a/Softeq.XToolkit.Bindings.Droid/Bindable/BindableViewHolder.cs b/Softeq.XToolkit.Bindings.Droid/Bindable/BindableViewHolder.cs
index 89d41d780..53a633ad4 100644
--- a/Softeq.XToolkit.Bindings.Droid/Bindable/BindableViewHolder.cs
+++ b/Softeq.XToolkit.Bindings.Droid/Bindable/BindableViewHolder.cs
@@ -7,6 +7,7 @@
using AndroidX.RecyclerView.Widget;
using Softeq.XToolkit.Bindings.Abstract;
using Softeq.XToolkit.Bindings.Extensions;
+using Softeq.XToolkit.Common.Disposables;
using Softeq.XToolkit.Common.Weak;
#nullable disable
@@ -16,10 +17,13 @@ namespace Softeq.XToolkit.Bindings.Droid.Bindable
public abstract class BindableViewHolder
: RecyclerView.ViewHolder, IBindableViewHolder
{
+ private readonly DisposableSubscriptionsComponent _subscriptionsComponent;
+
private IDisposable _itemViewClickSubscription;
protected BindableViewHolder(View itemView) : base(itemView)
{
+ _subscriptionsComponent = new DisposableSubscriptionsComponent(SetCommandsWithDisposing);
}
public event EventHandler ItemClicked;
@@ -63,11 +67,19 @@ protected virtual void OnItemViewClick(object sender, EventArgs e)
public virtual void DoAttachBindings()
{
+ _subscriptionsComponent.CreateSubscriptions();
}
public virtual void DoDetachBindings()
{
this.DetachBindings();
+
+ _subscriptionsComponent.DisposeSubscriptions();
+ }
+
+ protected virtual IEnumerable SetCommandsWithDisposing()
+ {
+ return [];
}
}
}
diff --git a/Softeq.XToolkit.Bindings.Droid/DroidBindingFactory.cs b/Softeq.XToolkit.Bindings.Droid/DroidBindingFactory.cs
index 2459e3fa0..96c834724 100644
--- a/Softeq.XToolkit.Bindings.Droid/DroidBindingFactory.cs
+++ b/Softeq.XToolkit.Bindings.Droid/DroidBindingFactory.cs
@@ -8,6 +8,7 @@
using System.Windows.Input;
using Android.Views;
using Android.Widget;
+using Softeq.XToolkit.Common.Disposables;
using Softeq.XToolkit.Common.Threading;
namespace Softeq.XToolkit.Bindings.Droid
@@ -147,18 +148,20 @@ public override Delegate GetCommandHandler(
}
///
- public override void HandleCommandCanExecute(
+ public override IDisposable HandleCommandCanExecute(
object element,
ICommand command,
Binding? commandParameterBinding)
{
if (element is View view)
{
- HandleViewEnabled(view, command, commandParameterBinding);
+ return HandleViewEnabled(view, command, commandParameterBinding);
}
+
+ return Disposable.Create(() => { });
}
- private static void HandleViewEnabled(
+ private static IDisposable HandleViewEnabled(
View view,
ICommand command,
Binding? commandParameterBinding)
@@ -171,20 +174,32 @@ private static void HandleViewEnabled(
() => view.Enabled = command.CanExecute(commandParameter));
// set by CanExecute
- command.CanExecuteChanged += (s, args) =>
- {
- Execute.BeginOnUIThread(
- () => view.Enabled = command.CanExecute(commandParameter));
- };
+ command.CanExecuteChanged += OnCommandCanExecuteChanged;
// set by bindable command parameter
if (commandParameterBinding != null)
{
- commandParameterBinding.ValueChanged += (s, args) =>
+ commandParameterBinding.ValueChanged += OnCommandParameterBindingValueChanged;
+ }
+
+ return Disposable.Create(() =>
+ {
+ if (commandParameterBinding != null)
{
- Execute.BeginOnUIThread(
- () => view.Enabled = command.CanExecute(commandParameterBinding.Value));
- };
+ commandParameterBinding.ValueChanged -= OnCommandParameterBindingValueChanged;
+ }
+
+ command.CanExecuteChanged -= OnCommandCanExecuteChanged;
+ });
+
+ void OnCommandCanExecuteChanged(object? s, EventArgs args)
+ {
+ Execute.BeginOnUIThread(() => view.Enabled = command.CanExecute(commandParameter));
+ }
+
+ void OnCommandParameterBindingValueChanged(object? s, EventArgs args)
+ {
+ Execute.BeginOnUIThread(() => view.Enabled = command.CanExecute(commandParameterBinding.Value));
}
}
}
diff --git a/Softeq.XToolkit.Bindings.Droid/Properties/AssemblyInfo.cs b/Softeq.XToolkit.Bindings.Droid/Properties/AssemblyInfo.cs
deleted file mode 100644
index 39b8e0f83..000000000
--- a/Softeq.XToolkit.Bindings.Droid/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Developed by Softeq Development Corporation
-// http://www.softeq.com
-
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Softeq.XToolkit.Bindings.Droid")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Softeq Development Corporation")]
-[assembly: AssemblyProduct("XToolkit.Bindings")]
-[assembly: AssemblyCopyright("Copyright © Softeq Development Corporation 2020")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Softeq.XToolkit.Bindings.Droid/Softeq.XToolkit.Bindings.Droid.csproj b/Softeq.XToolkit.Bindings.Droid/Softeq.XToolkit.Bindings.Droid.csproj
index 3b126c32d..0e094a945 100644
--- a/Softeq.XToolkit.Bindings.Droid/Softeq.XToolkit.Bindings.Droid.csproj
+++ b/Softeq.XToolkit.Bindings.Droid/Softeq.XToolkit.Bindings.Droid.csproj
@@ -1,84 +1,27 @@
-
-
+
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {2B4A678B-63B4-49DB-99B1-BFE7793110C4}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- Softeq.XToolkit.Bindings.Droid
- Softeq.XToolkit.Bindings.Droid
- 512
- Resources\Resource.Designer.cs
- Off
- v13.0
+ net8.0-android34.0
+ 21.0
+
true
- portable
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
None
+
- portable
- true
- bin\Release\
- TRACE
- prompt
- 4
SdkOnly
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {0F1F09A8-9CDB-4933-AA1B-898AB43D394C}
- Softeq.XToolkit.Bindings
-
-
- {18d3fdc1-b0a1-401e-87f2-1c43034e610c}
- Softeq.XToolkit.Common.Droid
-
-
- {24588814-B93D-4528-8917-9C2A3C4E85CA}
- Softeq.XToolkit.Common
-
+
-
-
\ No newline at end of file
+
+
diff --git a/Softeq.XToolkit.Bindings.Tests/Softeq.XToolkit.Bindings.Tests.csproj b/Softeq.XToolkit.Bindings.Tests/Softeq.XToolkit.Bindings.Tests.csproj
index 666e5710b..4bbaec837 100644
--- a/Softeq.XToolkit.Bindings.Tests/Softeq.XToolkit.Bindings.Tests.csproj
+++ b/Softeq.XToolkit.Bindings.Tests/Softeq.XToolkit.Bindings.Tests.csproj
@@ -1,8 +1,8 @@
+ net8.0
Exe
- net5.0
disable
diff --git a/Softeq.XToolkit.Bindings.iOS/AppleBindingFactory.cs b/Softeq.XToolkit.Bindings.iOS/AppleBindingFactory.cs
index d0700aeea..38d8df550 100644
--- a/Softeq.XToolkit.Bindings.iOS/AppleBindingFactory.cs
+++ b/Softeq.XToolkit.Bindings.iOS/AppleBindingFactory.cs
@@ -5,6 +5,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Windows.Input;
+using Softeq.XToolkit.Common.Disposables;
using UIKit;
namespace Softeq.XToolkit.Bindings.iOS
@@ -98,18 +99,20 @@ public override Binding CreateBinding(
}
///
- public override void HandleCommandCanExecute(
+ public override IDisposable HandleCommandCanExecute(
object element,
ICommand command,
Binding? commandParameterBinding)
{
if (element is UIControl control)
{
- HandleControlEnabled(control, command, commandParameterBinding);
+ return HandleControlEnabled(control, command, commandParameterBinding);
}
+
+ return Disposable.Create(() => { });
}
- private static void HandleControlEnabled(
+ private static IDisposable HandleControlEnabled(
UIControl control,
ICommand command,
Binding? commandParameterBinding)
@@ -122,20 +125,32 @@ private static void HandleControlEnabled(
() => control.Enabled = command.CanExecute(commandParameter));
// set by CanExecute
- command.CanExecuteChanged += (s, args) =>
- {
- control.BeginInvokeOnMainThread(
- () => control.Enabled = command.CanExecute(commandParameter));
- };
+ command.CanExecuteChanged += OnCommandCanExecuteChanged;
// set by bindable command parameter
if (commandParameterBinding != null)
{
- commandParameterBinding.ValueChanged += (s, args) =>
+ commandParameterBinding.ValueChanged += OnCommandParameterBindingValueChanged;
+ }
+
+ return Disposable.Create(() =>
+ {
+ if (commandParameterBinding != null)
{
- control.BeginInvokeOnMainThread(
- () => control.Enabled = command.CanExecute(commandParameterBinding.Value));
- };
+ commandParameterBinding.ValueChanged -= OnCommandParameterBindingValueChanged;
+ }
+
+ command.CanExecuteChanged -= OnCommandCanExecuteChanged;
+ });
+
+ void OnCommandCanExecuteChanged(object? s, EventArgs args)
+ {
+ control.BeginInvokeOnMainThread(() => control.Enabled = command.CanExecute(commandParameter));
+ }
+
+ void OnCommandParameterBindingValueChanged(object? s, EventArgs args)
+ {
+ control.BeginInvokeOnMainThread(() => control.Enabled = command.CanExecute(commandParameterBinding.Value));
}
}
}
diff --git a/Softeq.XToolkit.Bindings.iOS/Properties/AssemblyInfo.cs b/Softeq.XToolkit.Bindings.iOS/Properties/AssemblyInfo.cs
deleted file mode 100644
index 56877ab0c..000000000
--- a/Softeq.XToolkit.Bindings.iOS/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Developed by Softeq Development Corporation
-// http://www.softeq.com
-
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Softeq.XToolkit.Binding.iOS")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Softeq Development Corporation")]
-[assembly: AssemblyProduct("XToolkit.Bindings")]
-[assembly: AssemblyCopyright("Copyright © Softeq Development Corporation 2020")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("2d399ba9-1878-43e2-af05-6873eae9151b")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Softeq.XToolkit.Bindings.iOS/Softeq.XToolkit.Bindings.iOS.csproj b/Softeq.XToolkit.Bindings.iOS/Softeq.XToolkit.Bindings.iOS.csproj
index 67f3b4e21..4bff76dee 100644
--- a/Softeq.XToolkit.Bindings.iOS/Softeq.XToolkit.Bindings.iOS.csproj
+++ b/Softeq.XToolkit.Bindings.iOS/Softeq.XToolkit.Bindings.iOS.csproj
@@ -1,84 +1,24 @@
-
-
+
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {2D399BA9-1878-43E2-AF05-6873EAE9151B}
- {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Softeq.XToolkit.Bindings.iOS
- Softeq.XToolkit.Bindings.iOS
- Resources
+ net8.0-ios12.0
+ 10.0
+ false
+
true
- portable
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
- None
+ None
+
- portable
- true
- bin\Release
- prompt
- 4
- false
- SdkOnly
+ SdkOnly
+
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {0F1F09A8-9CDB-4933-AA1B-898AB43D394C}
- Softeq.XToolkit.Bindings
-
-
- {24588814-B93D-4528-8917-9C2A3C4E85CA}
- Softeq.XToolkit.Common
-
-
- {6BCB2009-2E46-458C-BCAA-AFC27A631924}
- Softeq.XToolkit.Common.iOS
-
-
-
+
\ No newline at end of file
diff --git a/Softeq.XToolkit.Bindings/BindingExtensions.cs b/Softeq.XToolkit.Bindings/BindingExtensions.cs
index 1ed231d5d..00547a239 100644
--- a/Softeq.XToolkit.Bindings/BindingExtensions.cs
+++ b/Softeq.XToolkit.Bindings/BindingExtensions.cs
@@ -544,6 +544,14 @@ public static void SetCommand(
HandleCommandCanExecute(element, command, castedBinding);
}
+ ///
+ public static IDisposable SetCommandWithDisposing(
+ this object element,
+ ICommand command)
+ {
+ return SetCommandWithDisposing(element, string.Empty, command);
+ }
+
///
/// Sets a to an object and actuates the command when a specific event is raised.
/// This method can only be used when the event uses a standard .
@@ -565,9 +573,13 @@ public static IDisposable SetCommandWithDisposing(
e.AddEventHandler(element, handler);
- HandleCommandCanExecute(element, command);
+ var canExecuteSubscriptions = HandleCommandCanExecute(element, command);
- return Disposable.Create(() => e.RemoveEventHandler(element, handler));
+ return Disposable.Create(() =>
+ {
+ canExecuteSubscriptions.Dispose();
+ e.RemoveEventHandler(element, handler);
+ });
}
///
@@ -659,19 +671,19 @@ internal static EventInfo GetEventInfoForControl(this Type type, string? eventNa
return info;
}
- private static void HandleCommandCanExecute(
+ private static IDisposable HandleCommandCanExecute(
object element,
ICommand command)
{
- HandleCommandCanExecute