diff --git a/src/Avalonia.Controls/Primitives/RangeBase.cs b/src/Avalonia.Controls/Primitives/RangeBase.cs index 33ab78b66f4..b54dd314f9f 100644 --- a/src/Avalonia.Controls/Primitives/RangeBase.cs +++ b/src/Avalonia.Controls/Primitives/RangeBase.cs @@ -10,6 +10,8 @@ namespace Avalonia.Controls.Primitives /// public abstract class RangeBase : TemplatedControl { + private bool _isDataContextChanging; + /// /// Defines the property. /// @@ -74,7 +76,7 @@ private static double CoerceMinimum(AvaloniaObject sender, double value) private void OnMinimumChanged() { - if (IsInitialized) + if (IsInitialized && !_isDataContextChanging) { CoerceValue(MaximumProperty); CoerceValue(ValueProperty); @@ -99,8 +101,9 @@ private static double CoerceMaximum(AvaloniaObject sender, double value) private void OnMaximumChanged() { - if (IsInitialized) + if (IsInitialized && !_isDataContextChanging) { + CoerceValue(MinimumProperty); CoerceValue(ValueProperty); } } @@ -170,6 +173,20 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang RaiseEvent(valueChangedEventArgs); } } + + /// + protected override void OnDataContextBeginUpdate() + { + _isDataContextChanging = true; + base.OnDataContextBeginUpdate(); + } + + /// + protected override void OnDataContextEndUpdate() + { + base.OnDataContextEndUpdate(); + _isDataContextChanging = false; + } /// /// Checks if the double value is not infinity nor NaN. diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs index 67d22ea30ee..e5d39212f73 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.Security.Cryptography.X509Certificates; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; @@ -27,6 +28,32 @@ public void Maximum_Should_Be_Coerced_To_Minimum() Assert.Equal(100, target.Maximum); } + [Fact] + public void ChangingDataContextShouldNotChangeOldDataContext() + { + var viewModel = new RangeTestViewModel() + { + Minimum = -5000, + Maximum = 5000, + Value = 4000 + }; + + var target = new TestRange + { + [!RangeBase.MinimumProperty] = new Binding(nameof(viewModel.Minimum)), + [!RangeBase.MaximumProperty] = new Binding(nameof(viewModel.Maximum)), + [!RangeBase.ValueProperty] = new Binding(nameof(viewModel.Value)), + }; + + var root = new TestRoot(target); + target.DataContext = viewModel; + target.DataContext = null; + + Assert.Equal(4000, viewModel.Value); + Assert.Equal(-5000, viewModel.Minimum); + Assert.Equal(5000, viewModel.Maximum); + } + [Fact] public void Value_Should_Be_Coerced_To_Range() { @@ -217,5 +244,12 @@ public double Value } } } + + private class RangeTestViewModel + { + public double Minimum { get; set; } + public double Maximum { get; set; } + public double Value { get; set; } + } } }