@ -10,6 +10,8 @@ namespace Avalonia.Controls
/// </summary>
/// </summary>
public class ScrollViewer : ContentControl , IScrollable , IScrollAnchorProvider
public class ScrollViewer : ContentControl , IScrollable , IScrollAnchorProvider
{
{
private static readonly Size s_defaultSmallChange = new Size ( 1 6 , 1 6 ) ;
/// <summary>
/// <summary>
/// Defines the <see cref="CanHorizontallyScroll"/> property.
/// Defines the <see cref="CanHorizontallyScroll"/> property.
/// </summary>
/// </summary>
@ -59,6 +61,22 @@ namespace Avalonia.Controls
o = > o . Viewport ,
o = > o . Viewport ,
( o , v ) = > o . Viewport = v ) ;
( o , v ) = > o . Viewport = v ) ;
/// <summary>
/// Defines the <see cref="LargeChange"/> property.
/// </summary>
public static readonly DirectProperty < ScrollViewer , Size > LargeChangeProperty =
AvaloniaProperty . RegisterDirect < ScrollViewer , Size > (
nameof ( LargeChange ) ,
o = > o . LargeChange ) ;
/// <summary>
/// Defines the <see cref="SmallChange"/> property.
/// </summary>
public static readonly DirectProperty < ScrollViewer , Size > SmallChangeProperty =
AvaloniaProperty . RegisterDirect < ScrollViewer , Size > (
nameof ( SmallChange ) ,
o = > o . SmallChange ) ;
/// <summary>
/// <summary>
/// Defines the HorizontalScrollBarMaximum property.
/// Defines the HorizontalScrollBarMaximum property.
/// </summary>
/// </summary>
@ -149,9 +167,13 @@ namespace Avalonia.Controls
nameof ( VerticalScrollBarVisibility ) ,
nameof ( VerticalScrollBarVisibility ) ,
ScrollBarVisibility . Auto ) ;
ScrollBarVisibility . Auto ) ;
private IDisposable _ childSubscription ;
private ILogicalScrollable _l ogicalScrollable ;
private Size _ extent ;
private Size _ extent ;
private Vector _ offset ;
private Vector _ offset ;
private Size _ viewport ;
private Size _ viewport ;
private Size _l argeChange ;
private Size _ smallChange = s_defaultSmallChange ;
/// <summary>
/// <summary>
/// Initializes static members of the <see cref="ScrollViewer"/> class.
/// Initializes static members of the <see cref="ScrollViewer"/> class.
@ -228,6 +250,16 @@ namespace Avalonia.Controls
}
}
}
}
/// <summary>
/// Gets the large (page) change value for the scroll viewer.
/// </summary>
public Size LargeChange = > _l argeChange ;
/// <summary>
/// Gets the small (line) change value for the scroll viewer.
/// </summary>
public Size SmallChange = > _ smallChange ;
/// <summary>
/// <summary>
/// Gets or sets the horizontal scrollbar visibility.
/// Gets or sets the horizontal scrollbar visibility.
/// </summary>
/// </summary>
@ -246,22 +278,6 @@ namespace Avalonia.Controls
set { SetValue ( VerticalScrollBarVisibilityProperty , value ) ; }
set { SetValue ( VerticalScrollBarVisibilityProperty , value ) ; }
}
}
/// <summary>
/// Scrolls to the top-left corner of the content.
/// </summary>
public void ScrollToHome ( )
{
Offset = new Vector ( double . NegativeInfinity , double . NegativeInfinity ) ;
}
/// <summary>
/// Scrolls to the bottom-left corner of the content.
/// </summary>
public void ScrollToEnd ( )
{
Offset = new Vector ( double . NegativeInfinity , double . PositiveInfinity ) ;
}
/// <summary>
/// <summary>
/// Gets a value indicating whether the viewer can scroll horizontally.
/// Gets a value indicating whether the viewer can scroll horizontally.
/// </summary>
/// </summary>
@ -347,6 +363,22 @@ namespace Avalonia.Controls
/// <inheritdoc/>
/// <inheritdoc/>
IControl IScrollAnchorProvider . CurrentAnchor = > null ; // TODO: Implement
IControl IScrollAnchorProvider . CurrentAnchor = > null ; // TODO: Implement
/// <summary>
/// Scrolls to the top-left corner of the content.
/// </summary>
public void ScrollToHome ( )
{
Offset = new Vector ( double . NegativeInfinity , double . NegativeInfinity ) ;
}
/// <summary>
/// Scrolls to the bottom-left corner of the content.
/// </summary>
public void ScrollToEnd ( )
{
Offset = new Vector ( double . NegativeInfinity , double . PositiveInfinity ) ;
}
/// <summary>
/// <summary>
/// Gets the value of the HorizontalScrollBarVisibility attached property.
/// Gets the value of the HorizontalScrollBarVisibility attached property.
/// </summary>
/// </summary>
@ -397,6 +429,22 @@ namespace Avalonia.Controls
// TODO: Implement
// TODO: Implement
}
}
protected override bool RegisterContentPresenter ( IContentPresenter presenter )
{
_ childSubscription ? . Dispose ( ) ;
_ childSubscription = null ;
if ( base . RegisterContentPresenter ( presenter ) )
{
_ childSubscription = Presenter ?
. GetObservable ( ContentPresenter . ChildProperty )
. Subscribe ( ChildChanged ) ;
return true ;
}
return false ;
}
internal static Vector CoerceOffset ( Size extent , Size viewport , Vector offset )
internal static Vector CoerceOffset ( Size extent , Size viewport , Vector offset )
{
{
var maxX = Math . Max ( extent . Width - viewport . Width , 0 ) ;
var maxX = Math . Max ( extent . Width - viewport . Width , 0 ) ;
@ -431,6 +479,28 @@ namespace Avalonia.Controls
}
}
}
}
private void ChildChanged ( IControl child )
{
if ( _l ogicalScrollable is object )
{
_l ogicalScrollable . ScrollInvalidated - = LogicalScrollInvalidated ;
_l ogicalScrollable = null ;
}
if ( child is ILogicalScrollable logical )
{
_l ogicalScrollable = logical ;
logical . ScrollInvalidated + = LogicalScrollInvalidated ;
}
CalculatedPropertiesChanged ( ) ;
}
private void LogicalScrollInvalidated ( object sender , EventArgs e )
{
CalculatedPropertiesChanged ( ) ;
}
private void ScrollBarVisibilityChanged ( AvaloniaPropertyChangedEventArgs e )
private void ScrollBarVisibilityChanged ( AvaloniaPropertyChangedEventArgs e )
{
{
var wasEnabled = ! ScrollBarVisibility . Disabled . Equals ( e . OldValue ) ;
var wasEnabled = ! ScrollBarVisibility . Disabled . Equals ( e . OldValue ) ;
@ -465,6 +535,17 @@ namespace Avalonia.Controls
RaisePropertyChanged ( VerticalScrollBarMaximumProperty , 0 , VerticalScrollBarMaximum ) ;
RaisePropertyChanged ( VerticalScrollBarMaximumProperty , 0 , VerticalScrollBarMaximum ) ;
RaisePropertyChanged ( VerticalScrollBarValueProperty , 0 , VerticalScrollBarValue ) ;
RaisePropertyChanged ( VerticalScrollBarValueProperty , 0 , VerticalScrollBarValue ) ;
RaisePropertyChanged ( VerticalScrollBarViewportSizeProperty , 0 , VerticalScrollBarViewportSize ) ;
RaisePropertyChanged ( VerticalScrollBarViewportSizeProperty , 0 , VerticalScrollBarViewportSize ) ;
if ( _l ogicalScrollable ? . IsLogicalScrollEnabled = = true )
{
SetAndRaise ( SmallChangeProperty , ref _ smallChange , _l ogicalScrollable . ScrollSize ) ;
SetAndRaise ( LargeChangeProperty , ref _l argeChange , _l ogicalScrollable . PageScrollSize ) ;
}
else
{
SetAndRaise ( SmallChangeProperty , ref _ smallChange , s_defaultSmallChange ) ;
SetAndRaise ( LargeChangeProperty , ref _l argeChange , Viewport ) ;
}
}
}
protected override void OnKeyDown ( KeyEventArgs e )
protected override void OnKeyDown ( KeyEventArgs e )