diff --git a/src/Perspex.Controls/Presenters/ScrollContentPresenter.cs b/src/Perspex.Controls/Presenters/ScrollContentPresenter.cs index d8cc99105f..b7b225ae2b 100644 --- a/src/Perspex.Controls/Presenters/ScrollContentPresenter.cs +++ b/src/Perspex.Controls/Presenters/ScrollContentPresenter.cs @@ -21,19 +21,25 @@ namespace Perspex.Controls.Presenters /// Defines the property. /// public static readonly PerspexProperty ExtentProperty = - ScrollViewer.ExtentProperty.AddOwner(); + ScrollViewer.ExtentProperty.AddOwner( + o => o.Extent, + (o, v) => o.Extent = v); /// /// Defines the property. /// public static readonly PerspexProperty OffsetProperty = - ScrollViewer.OffsetProperty.AddOwner(); + ScrollViewer.OffsetProperty.AddOwner( + o => o.Offset, + (o, v) => o.Offset = v); /// /// Defines the property. /// public static readonly PerspexProperty ViewportProperty = - ScrollViewer.ViewportProperty.AddOwner(); + ScrollViewer.ViewportProperty.AddOwner( + o => o.Viewport, + (o, v) => o.Viewport = v); /// /// Defines the property. @@ -41,8 +47,11 @@ namespace Perspex.Controls.Presenters public static readonly PerspexProperty CanScrollHorizontallyProperty = PerspexProperty.Register("CanScrollHorizontally", true); + private Size _extent; private Size _measuredExtent; + private Vector _offset; private IDisposable _scrollableSubscription; + private Size _viewport; /// /// Initializes static members of the class. @@ -69,8 +78,8 @@ namespace Perspex.Controls.Presenters /// public Size Extent { - get { return GetValue(ExtentProperty); } - private set { SetValue(ExtentProperty, value); } + get { return _extent; } + private set { SetAndRaise(ExtentProperty, ref _extent, value); } } /// @@ -78,8 +87,8 @@ namespace Perspex.Controls.Presenters /// public Vector Offset { - get { return GetValue(OffsetProperty); } - set { SetValue(OffsetProperty, value); } + get { return _offset; } + set { SetAndRaise(OffsetProperty, ref _offset, value); } } /// @@ -87,8 +96,8 @@ namespace Perspex.Controls.Presenters /// public Size Viewport { - get { return GetValue(ViewportProperty); } - private set { SetValue(ViewportProperty, value); } + get { return _viewport; } + private set { SetAndRaise(ViewportProperty, ref _viewport, value); } } /// diff --git a/src/Perspex.Controls/Primitives/RangeBase.cs b/src/Perspex.Controls/Primitives/RangeBase.cs index 430ffbd766..69a6db645c 100644 --- a/src/Perspex.Controls/Primitives/RangeBase.cs +++ b/src/Perspex.Controls/Primitives/RangeBase.cs @@ -15,34 +15,38 @@ namespace Perspex.Controls.Primitives /// Defines the property. /// public static readonly PerspexProperty MinimumProperty = - PerspexProperty.Register( + PerspexProperty.RegisterDirect( nameof(Minimum), - validate: ValidateMinimum); + o => o.Minimum, + (o, v) => o.Minimum = v); /// /// Defines the property. /// public static readonly PerspexProperty MaximumProperty = - PerspexProperty.Register( + PerspexProperty.RegisterDirect( nameof(Maximum), - defaultValue: 100.0, - validate: ValidateMaximum); + o => o.Maximum, + (o, v) => o.Maximum = v); /// /// Defines the property. /// public static readonly PerspexProperty ValueProperty = - PerspexProperty.Register( + PerspexProperty.RegisterDirect( nameof(Value), - validate: ValidateValue); + o => o.Value, + (o, v) => o.Value = v); + + private double _minimum; + private double _maximum = 100.0; + private double _value; /// /// Initializes a new instance of the class. /// public RangeBase() { - AffectsValidation(MinimumProperty, MaximumProperty, ValueProperty); - AffectsValidation(MaximumProperty, ValueProperty); } /// @@ -50,8 +54,18 @@ namespace Perspex.Controls.Primitives /// public double Minimum { - get { return GetValue(MinimumProperty); } - set { SetValue(MinimumProperty, value); } + get + { + return _minimum; + } + + set + { + value = ValidateMinimum(value); + SetAndRaise(MinimumProperty, ref _minimum, value); + Maximum = ValidateMaximum(Maximum); + Value = ValidateValue(Value); + } } /// @@ -59,8 +73,17 @@ namespace Perspex.Controls.Primitives /// public double Maximum { - get { return GetValue(MaximumProperty); } - set { SetValue(MaximumProperty, value); } + get + { + return _maximum; + } + + set + { + value = ValidateMaximum(value); + SetAndRaise(MaximumProperty, ref _maximum, value); + Value = ValidateValue(Value); + } } /// @@ -68,8 +91,16 @@ namespace Perspex.Controls.Primitives /// public double Value { - get { return GetValue(ValueProperty); } - set { SetValue(ValueProperty, value); } + get + { + return _value; + } + + set + { + value = ValidateValue(value); + SetAndRaise(ValueProperty, ref _value, value); + } } /// @@ -88,10 +119,9 @@ namespace Perspex.Controls.Primitives /// /// Validates the property. /// - /// The RangeBase control. /// The value. /// The coerced value. - private static double ValidateMinimum(RangeBase sender, double value) + private double ValidateMinimum(double value) { ValidateDouble(value, "Minimum"); return value; @@ -100,25 +130,23 @@ namespace Perspex.Controls.Primitives /// /// Validates/coerces the property. /// - /// The RangeBase control. /// The value. /// The coerced value. - private static double ValidateMaximum(RangeBase sender, double value) + private double ValidateMaximum(double value) { ValidateDouble(value, "Maximum"); - return Math.Max(value, sender.Minimum); + return Math.Max(value, Minimum); } /// /// Validates/coerces the property. /// - /// The RangeBase control. /// The value. /// The coerced value. - private static double ValidateValue(RangeBase sender, double value) + private double ValidateValue(double value) { ValidateDouble(value, "Value"); - return MathUtilities.Clamp(value, sender.Minimum, sender.Maximum); + return MathUtilities.Clamp(value, Minimum, Maximum); } } } diff --git a/src/Perspex.Controls/Primitives/Track.cs b/src/Perspex.Controls/Primitives/Track.cs index 6fe4f3811b..238b633050 100644 --- a/src/Perspex.Controls/Primitives/Track.cs +++ b/src/Perspex.Controls/Primitives/Track.cs @@ -11,13 +11,13 @@ namespace Perspex.Controls.Primitives public class Track : Control { public static readonly PerspexProperty MinimumProperty = - RangeBase.MinimumProperty.AddOwner(); + RangeBase.MinimumProperty.AddOwner(o => o.Minimum, (o,v) => o.Minimum = v); public static readonly PerspexProperty MaximumProperty = - RangeBase.MaximumProperty.AddOwner(); + RangeBase.MaximumProperty.AddOwner(o => o.Maximum, (o, v) => o.Maximum = v); public static readonly PerspexProperty ValueProperty = - RangeBase.ValueProperty.AddOwner(); + RangeBase.ValueProperty.AddOwner(o => o.Value, (o, v) => o.Value = v); public static readonly PerspexProperty ViewportSizeProperty = ScrollBar.ViewportSizeProperty.AddOwner(); @@ -28,6 +28,10 @@ namespace Perspex.Controls.Primitives public static readonly PerspexProperty ThumbProperty = PerspexProperty.Register("Thumb"); + private double _minimum; + private double _maximum = 100.0; + private double _value; + static Track() { AffectsArrange(MinimumProperty); @@ -57,20 +61,20 @@ namespace Perspex.Controls.Primitives public double Minimum { - get { return GetValue(MinimumProperty); } - set { SetValue(MinimumProperty, value); } + get { return _minimum; } + set { SetAndRaise(MinimumProperty, ref _minimum, value); } } public double Maximum { - get { return GetValue(MaximumProperty); } - set { SetValue(MaximumProperty, value); } + get { return _maximum; } + set { SetAndRaise(MaximumProperty, ref _maximum, value); } } public double Value { - get { return GetValue(ValueProperty); } - set { SetValue(ValueProperty, value); } + get { return _value; } + set { SetAndRaise(ValueProperty, ref _value, value); } } public double ViewportSize diff --git a/src/Perspex.Controls/ScrollViewer.cs b/src/Perspex.Controls/ScrollViewer.cs index bdd770617b..8fa2814727 100644 --- a/src/Perspex.Controls/ScrollViewer.cs +++ b/src/Perspex.Controls/ScrollViewer.cs @@ -26,19 +26,26 @@ namespace Perspex.Controls /// Defines the property. /// public static readonly PerspexProperty ExtentProperty = - PerspexProperty.Register(nameof(Extent)); + PerspexProperty.RegisterDirect(nameof(Extent), + o => o.Extent, + (o, v) => o.Extent = v); /// /// Defines the property. /// public static readonly PerspexProperty OffsetProperty = - PerspexProperty.Register(nameof(Offset), validate: ValidateOffset); + PerspexProperty.RegisterDirect( + nameof(Offset), + o => o.Offset, + (o, v) => o.Offset = v); /// /// Defines the property. /// public static readonly PerspexProperty ViewportProperty = - PerspexProperty.Register(nameof(Viewport)); + PerspexProperty.RegisterDirect(nameof(Viewport), + o => o.Viewport, + (o, v) => o.Viewport = v); /// /// Defines the HorizontalScrollBarMaximum property. @@ -120,6 +127,10 @@ namespace Perspex.Controls nameof(VerticalScrollBarVisibility), ScrollBarVisibility.Auto); + private Size _extent; + private Vector _offset; + private Size _viewport; + /// /// Initializes static members of the class. /// @@ -173,8 +184,8 @@ namespace Perspex.Controls /// public Size Extent { - get { return GetValue(ExtentProperty); } - private set { SetValue(ExtentProperty, value); } + get { return _extent; } + private set { SetAndRaise(ExtentProperty, ref _extent, value); } } /// @@ -182,8 +193,16 @@ namespace Perspex.Controls /// public Vector Offset { - get { return GetValue(OffsetProperty); } - set { SetValue(OffsetProperty, value); } + get + { + return _offset; + } + + set + { + value = ValidateOffset(this, value); + SetAndRaise(OffsetProperty, ref _offset, value); + } } /// @@ -191,8 +210,8 @@ namespace Perspex.Controls /// public Size Viewport { - get { return GetValue(ViewportProperty); } - private set { SetValue(ViewportProperty, value); } + get { return _viewport; } + private set { SetAndRaise(ViewportProperty, ref _viewport, value); } } /// diff --git a/tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs b/tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs index 4f56587bb5..3c761a2041 100644 --- a/tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs +++ b/tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs @@ -218,17 +218,6 @@ namespace Perspex.Controls.UnitTests.Presenters Assert.False(target.IsArrangeValid); } - [Fact] - public void Offset_Should_Be_Coerced_To_Viewport() - { - var target = new ScrollContentPresenter(); - target.SetValue(ScrollContentPresenter.ExtentProperty, new Size(20, 20)); - target.SetValue(ScrollContentPresenter.ViewportProperty, new Size(10, 10)); - target.Offset = new Vector(12, 12); - - Assert.Equal(new Vector(10, 10), target.Offset); - } - [Fact] public void BringDescendentIntoView_Should_Update_Offset() {