diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index fd8d441f..01b70b16 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -131,10 +131,6 @@
-
- $(Features);runtime-async=on
-
-
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 1774e900..104cfb8b 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -16,7 +16,7 @@
-
+
diff --git a/src/ReactiveUI.Binding.Shared/Fallback/RuntimeCommandBindingFallback.cs b/src/ReactiveUI.Binding.Shared/Fallback/RuntimeCommandBindingFallback.cs
index 67dfa2b6..ac951f90 100644
--- a/src/ReactiveUI.Binding.Shared/Fallback/RuntimeCommandBindingFallback.cs
+++ b/src/ReactiveUI.Binding.Shared/Fallback/RuntimeCommandBindingFallback.cs
@@ -61,7 +61,7 @@ public static IDisposable BindCommand<
return EmptyDisposable.Instance;
}
- var binding = new MutableDisposable();
+ var binding = new SwapDisposable();
var commands = RuntimeObservationFallback.WhenAnyValue(viewModel, commandProperty);
var controls = RuntimeObservationFallback.WhenAnyValue(view, controlProperty);
diff --git a/src/ReactiveUI.Binding.Shared/Fallback/RuntimeInteractionFallback.cs b/src/ReactiveUI.Binding.Shared/Fallback/RuntimeInteractionFallback.cs
index 690f136b..87307314 100644
--- a/src/ReactiveUI.Binding.Shared/Fallback/RuntimeInteractionFallback.cs
+++ b/src/ReactiveUI.Binding.Shared/Fallback/RuntimeInteractionFallback.cs
@@ -50,7 +50,7 @@ public static IDisposable BindInteraction(
return EmptyDisposable.Instance;
}
- var registration = new MutableDisposable();
+ var registration = new SwapDisposable();
var observation = BindingErrors.Subscribe(
RuntimeObservationFallback.WhenAnyValue(viewModel, interactionProperty),
interaction => registration.Disposable = interaction is null
diff --git a/src/benchmarks/ReactiveUI.Binding.Benchmarks.ReactiveUI/ReactiveUIToPropertyBenchmark.cs b/src/benchmarks/ReactiveUI.Binding.Benchmarks.ReactiveUI/ReactiveUIToPropertyBenchmark.cs
index d7ba0312..8ccfcee4 100644
--- a/src/benchmarks/ReactiveUI.Binding.Benchmarks.ReactiveUI/ReactiveUIToPropertyBenchmark.cs
+++ b/src/benchmarks/ReactiveUI.Binding.Benchmarks.ReactiveUI/ReactiveUIToPropertyBenchmark.cs
@@ -102,14 +102,14 @@ protected virtual void Dispose(bool disposing)
private void OnPropertyChanged(object? sender, PropertyChangedEventArgs args) => _notifications++;
/// A ReactiveObject whose derived property is backed by ReactiveUI's helper.
- private sealed class CountViewModel : ReactiveObject, IDisposable
+ internal sealed class CountViewModel : ReactiveObject, IDisposable
{
/// Backs .
private readonly ObservableAsPropertyHelper _count;
/// Initializes a new instance of the class.
/// The values takes.
- public CountViewModel(IObservable counts) => _count = counts.ToProperty(this, x => x.Count);
+ public CountViewModel(IObservable counts) => _count = counts.ToProperty(this, static x => x.Count);
/// Gets the latest count.
public int Count => _count.Value;
diff --git a/src/benchmarks/ReactiveUI.Binding.Benchmarks/RxUiDynamicChainBaseline.cs b/src/benchmarks/ReactiveUI.Binding.Benchmarks/RxUiDynamicChainBaseline.cs
index 619a16b9..33c69109 100644
--- a/src/benchmarks/ReactiveUI.Binding.Benchmarks/RxUiDynamicChainBaseline.cs
+++ b/src/benchmarks/ReactiveUI.Binding.Benchmarks/RxUiDynamicChainBaseline.cs
@@ -8,7 +8,6 @@
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
-using ReactiveUI;
using ReactiveUI.Builder;
using BenchmarkVm = ReactiveUI.Binding.Benchmarks.Mocks.BenchmarkViewModel;
diff --git a/src/tests/ReactiveUI.Binding.Tests/Fallback/RuntimeCommandBindingFallbackTests.cs b/src/tests/ReactiveUI.Binding.Tests/Fallback/RuntimeCommandBindingFallbackTests.cs
index 4968ab70..48869ece 100644
--- a/src/tests/ReactiveUI.Binding.Tests/Fallback/RuntimeCommandBindingFallbackTests.cs
+++ b/src/tests/ReactiveUI.Binding.Tests/Fallback/RuntimeCommandBindingFallbackTests.cs
@@ -2,6 +2,8 @@
// ReactiveUI and Contributors licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
using System.Windows.Input;
using ReactiveUI.Binding.Fallback;
using ReactiveUI.Binding.Tests.TestModels;
@@ -90,4 +92,90 @@ public async Task BindCommand_WithANamedEventAndAControlNoBinderReaches_BindsNot
await Assert.That(command.LastParameter).IsNull();
}
+
+ /// A change notification on a link of the control chain rebinds without leaving the old binding attached.
+ /// A task representing the asynchronous test operation.
+ [Test]
+ public async Task BindCommand_WhenAChainLinkRaisesChanged_KeepsOneActiveBinding()
+ {
+ RuntimeObservationFallbackTests.EnsureInitialized();
+ Locator.CurrentMutable.RegisterConstant(new ClickCommandBinder());
+ var command = new RecordingStubCommand();
+ var viewModel = new DispatchStubViewModel { Run = command };
+ var view = new ChainedView();
+
+ using var binding = RuntimeCommandBindingFallback.BindCommand(
+ view,
+ viewModel,
+ x => x.Run,
+ x => x.Editor.Properties.Button,
+ new ManualObservable