Browse Source

Merge pull request #1348 from AvaloniaUI/fixes/1344-listbox-horizontal-scrollbar

Allow disabling of scrollbars in ListBox.
pull/1276/merge
Jeremy Koritzinsky 8 years ago
committed by GitHub
parent
commit
9378d6266b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      samples/VirtualizationTest/MainWindow.xaml
  2. 18
      samples/VirtualizationTest/ViewModels/MainWindowViewModel.cs
  3. 12
      src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
  4. 27
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  5. 63
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  6. 10
      src/Avalonia.Controls/Primitives/ILogicalScrollable.cs
  7. 1
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  8. 3
      src/Avalonia.Controls/Primitives/ScrollBarVisibility.cs
  9. 97
      src/Avalonia.Controls/ScrollViewer.cs
  10. 22
      src/Avalonia.Controls/TextBox.cs
  11. 2
      src/Avalonia.Controls/VirtualizingStackPanel.cs
  12. 7
      src/Avalonia.Themes.Default/ListBox.xaml
  13. 5
      src/Avalonia.Themes.Default/ScrollViewer.xaml
  14. 3
      src/Avalonia.Themes.Default/TextBox.xaml
  15. 2
      src/Avalonia.Themes.Default/TreeView.xaml
  16. 2
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
  17. 2
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
  18. 11
      tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs
  19. 46
      tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_ILogicalScrollable.cs
  20. 30
      tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs
  21. 2
      tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs
  22. 2
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs
  23. 2
      tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs

12
samples/VirtualizationTest/MainWindow.xaml

@ -21,6 +21,12 @@
<TextBox Watermark="Viewport" <TextBox Watermark="Viewport"
UseFloatingWatermark="True" UseFloatingWatermark="True"
Text="{Binding #listBox.Scroll.Viewport, Mode=OneWay}"/> Text="{Binding #listBox.Scroll.Viewport, Mode=OneWay}"/>
<TextBlock>Horiz. ScrollBar</TextBlock>
<DropDown Items="{Binding ScrollBarVisibilities}"
SelectedItem="{Binding HorizontalScrollBarVisibility}"/>
<TextBlock>Vert. ScrollBar</TextBlock>
<DropDown Items="{Binding ScrollBarVisibilities}"
SelectedItem="{Binding VerticalScrollBarVisibility}"/>
<TextBox Watermark="Item to Create" <TextBox Watermark="Item to Create"
UseFloatingWatermark="True" UseFloatingWatermark="True"
Text="{Binding NewItemString}"/> Text="{Binding NewItemString}"/>
@ -35,7 +41,9 @@
Items="{Binding Items}" Items="{Binding Items}"
SelectedItems="{Binding SelectedItems}" SelectedItems="{Binding SelectedItems}"
SelectionMode="Multiple" SelectionMode="Multiple"
VirtualizationMode="{Binding VirtualizationMode}"> VirtualizationMode="{Binding VirtualizationMode}"
ScrollViewer.HorizontalScrollBarVisibility="{Binding HorizontalScrollBarVisibility, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="{Binding VerticalScrollBarVisibility, Mode=TwoWay}">
<ListBox.ItemsPanel> <ListBox.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="{Binding Orientation}"/> <VirtualizingStackPanel Orientation="{Binding Orientation}"/>
@ -43,7 +51,7 @@
</ListBox.ItemsPanel> </ListBox.ItemsPanel>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding Header}"/> <TextBlock Text="{Binding Header}" TextWrapping="Wrap"/>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>

18
samples/VirtualizationTest/ViewModels/MainWindowViewModel.cs

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using ReactiveUI; using ReactiveUI;
namespace VirtualizationTest.ViewModels namespace VirtualizationTest.ViewModels
@ -17,6 +18,8 @@ namespace VirtualizationTest.ViewModels
private int _newItemIndex; private int _newItemIndex;
private IReactiveList<ItemViewModel> _items; private IReactiveList<ItemViewModel> _items;
private string _prefix = "Item"; private string _prefix = "Item";
private ScrollBarVisibility _horizontalScrollBarVisibility = ScrollBarVisibility.Auto;
private ScrollBarVisibility _verticalScrollBarVisibility = ScrollBarVisibility.Auto;
private Orientation _orientation = Orientation.Vertical; private Orientation _orientation = Orientation.Vertical;
private ItemVirtualizationMode _virtualizationMode = ItemVirtualizationMode.Simple; private ItemVirtualizationMode _virtualizationMode = ItemVirtualizationMode.Simple;
@ -64,6 +67,21 @@ namespace VirtualizationTest.ViewModels
public IEnumerable<Orientation> Orientations => public IEnumerable<Orientation> Orientations =>
Enum.GetValues(typeof(Orientation)).Cast<Orientation>(); Enum.GetValues(typeof(Orientation)).Cast<Orientation>();
public ScrollBarVisibility HorizontalScrollBarVisibility
{
get { return _horizontalScrollBarVisibility; }
set { this.RaiseAndSetIfChanged(ref _horizontalScrollBarVisibility, value); }
}
public ScrollBarVisibility VerticalScrollBarVisibility
{
get { return _verticalScrollBarVisibility; }
set { this.RaiseAndSetIfChanged(ref _verticalScrollBarVisibility, value); }
}
public IEnumerable<ScrollBarVisibility> ScrollBarVisibilities =>
Enum.GetValues(typeof(ScrollBarVisibility)).Cast<ScrollBarVisibility>();
public ItemVirtualizationMode VirtualizationMode public ItemVirtualizationMode VirtualizationMode
{ {
get { return _virtualizationMode; } get { return _virtualizationMode; }

12
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@ -5,6 +5,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Utils; using Avalonia.Controls.Utils;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Layout; using Avalonia.Layout;
@ -97,6 +98,7 @@ namespace Avalonia.Controls.Presenters
/// <inheritdoc/> /// <inheritdoc/>
public override Size MeasureOverride(Size availableSize) public override Size MeasureOverride(Size availableSize)
{ {
var scrollable = (ILogicalScrollable)Owner;
var visualRoot = Owner.GetVisualRoot(); var visualRoot = Owner.GetVisualRoot();
var maxAvailableSize = (visualRoot as WindowBase)?.PlatformImpl?.MaxClientSize var maxAvailableSize = (visualRoot as WindowBase)?.PlatformImpl?.MaxClientSize
?? (visualRoot as TopLevel)?.ClientSize; ?? (visualRoot as TopLevel)?.ClientSize;
@ -115,7 +117,10 @@ namespace Avalonia.Controls.Presenters
} }
} }
availableSize = availableSize.WithWidth(double.PositiveInfinity); if (scrollable.CanHorizontallyScroll)
{
availableSize = availableSize.WithWidth(double.PositiveInfinity);
}
} }
else else
{ {
@ -127,7 +132,10 @@ namespace Avalonia.Controls.Presenters
} }
} }
availableSize = availableSize.WithHeight(double.PositiveInfinity); if (scrollable.CanVerticallyScroll)
{
availableSize = availableSize.WithHeight(double.PositiveInfinity);
}
} }
Owner.Panel.Measure(availableSize); Owner.Panel.Measure(availableSize);

27
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@ -23,6 +23,8 @@ namespace Avalonia.Controls.Presenters
defaultValue: ItemVirtualizationMode.None); defaultValue: ItemVirtualizationMode.None);
private ItemVirtualizer _virtualizer; private ItemVirtualizer _virtualizer;
private bool _canHorizontallyScroll;
private bool _canVerticallyScroll;
/// <summary> /// <summary>
/// Initializes static members of the <see cref="ItemsPresenter"/> class. /// Initializes static members of the <see cref="ItemsPresenter"/> class.
@ -46,6 +48,31 @@ namespace Avalonia.Controls.Presenters
set { SetValue(VirtualizationModeProperty, value); } set { SetValue(VirtualizationModeProperty, value); }
} }
/// <summary>
/// Gets or sets a value indicating whether the content can be scrolled horizontally.
/// </summary>
bool ILogicalScrollable.CanHorizontallyScroll
{
get { return _canHorizontallyScroll; }
set
{
_canHorizontallyScroll = value;
InvalidateMeasure();
}
}
/// <summary>
/// Gets or sets a value indicating whether the content can be scrolled horizontally.
/// </summary>
bool ILogicalScrollable.CanVerticallyScroll
{
get { return _canVerticallyScroll; }
set
{
_canVerticallyScroll = value;
InvalidateMeasure();
}
}
/// <inheritdoc/> /// <inheritdoc/>
bool ILogicalScrollable.IsLogicalScrollEnabled bool ILogicalScrollable.IsLogicalScrollEnabled
{ {

63
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -17,6 +17,24 @@ namespace Avalonia.Controls.Presenters
/// </summary> /// </summary>
public class ScrollContentPresenter : ContentPresenter, IPresenter, IScrollable public class ScrollContentPresenter : ContentPresenter, IPresenter, IScrollable
{ {
/// <summary>
/// Defines the <see cref="CanHorizontallyScroll"/> property.
/// </summary>
public static readonly DirectProperty<ScrollContentPresenter, bool> CanHorizontallyScrollProperty =
AvaloniaProperty.RegisterDirect<ScrollContentPresenter, bool>(
nameof(CanHorizontallyScroll),
o => o.CanHorizontallyScroll,
(o, v) => o.CanHorizontallyScroll = v);
/// <summary>
/// Defines the <see cref="CanVerticallyScroll"/> property.
/// </summary>
public static readonly DirectProperty<ScrollContentPresenter, bool> CanVerticallyScrollProperty =
AvaloniaProperty.RegisterDirect<ScrollContentPresenter, bool>(
nameof(CanVerticallyScroll),
o => o.CanVerticallyScroll,
(o, v) => o.CanVerticallyScroll = v);
/// <summary> /// <summary>
/// Defines the <see cref="Extent"/> property. /// Defines the <see cref="Extent"/> property.
/// </summary> /// </summary>
@ -41,12 +59,8 @@ namespace Avalonia.Controls.Presenters
o => o.Viewport, o => o.Viewport,
(o, v) => o.Viewport = v); (o, v) => o.Viewport = v);
/// <summary> private bool _canHorizontallyScroll;
/// Defines the <see cref="CanScrollHorizontally"/> property. private bool _canVerticallyScroll;
/// </summary>
public static readonly StyledProperty<bool> CanScrollHorizontallyProperty =
ScrollViewer.CanScrollHorizontallyProperty.AddOwner<ScrollContentPresenter>();
private Size _extent; private Size _extent;
private Size _measuredExtent; private Size _measuredExtent;
private Vector _offset; private Vector _offset;
@ -73,6 +87,24 @@ namespace Avalonia.Controls.Presenters
this.GetObservable(ChildProperty).Subscribe(UpdateScrollableSubscription); this.GetObservable(ChildProperty).Subscribe(UpdateScrollableSubscription);
} }
/// <summary>
/// Gets or sets a value indicating whether the content can be scrolled horizontally.
/// </summary>
public bool CanHorizontallyScroll
{
get { return _canHorizontallyScroll; }
set { SetAndRaise(CanHorizontallyScrollProperty, ref _canHorizontallyScroll, value); }
}
/// <summary>
/// Gets or sets a value indicating whether the content can be scrolled horizontally.
/// </summary>
public bool CanVerticallyScroll
{
get { return _canVerticallyScroll; }
set { SetAndRaise(CanVerticallyScrollProperty, ref _canVerticallyScroll, value); }
}
/// <summary> /// <summary>
/// Gets the extent of the scrollable content. /// Gets the extent of the scrollable content.
/// </summary> /// </summary>
@ -100,11 +132,6 @@ namespace Avalonia.Controls.Presenters
private set { SetAndRaise(ViewportProperty, ref _viewport, value); } private set { SetAndRaise(ViewportProperty, ref _viewport, value); }
} }
/// <summary>
/// Gets a value indicating whether the content can be scrolled horizontally.
/// </summary>
public bool CanScrollHorizontally => GetValue(CanScrollHorizontallyProperty);
/// <summary> /// <summary>
/// Attempts to bring a portion of the target visual into view by scrolling the content. /// Attempts to bring a portion of the target visual into view by scrolling the content.
/// </summary> /// </summary>
@ -182,10 +209,15 @@ namespace Avalonia.Controls.Presenters
{ {
measureSize = new Size(double.PositiveInfinity, double.PositiveInfinity); measureSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
if (!CanScrollHorizontally) if (!CanHorizontallyScroll)
{ {
measureSize = measureSize.WithWidth(availableSize.Width); measureSize = measureSize.WithWidth(availableSize.Width);
} }
if (!CanVerticallyScroll)
{
measureSize = measureSize.WithHeight(availableSize.Height);
}
} }
child.Measure(measureSize); child.Measure(measureSize);
@ -289,7 +321,12 @@ namespace Avalonia.Controls.Presenters
if (scrollable.IsLogicalScrollEnabled == true) if (scrollable.IsLogicalScrollEnabled == true)
{ {
_logicalScrollSubscription = new CompositeDisposable( _logicalScrollSubscription = new CompositeDisposable(
this.GetObservable(OffsetProperty).Skip(1).Subscribe(x => scrollable.Offset = x), this.GetObservable(CanHorizontallyScrollProperty)
.Subscribe(x => scrollable.CanHorizontallyScroll = x),
this.GetObservable(CanVerticallyScrollProperty)
.Subscribe(x => scrollable.CanVerticallyScroll = x),
this.GetObservable(OffsetProperty)
.Skip(1).Subscribe(x => scrollable.Offset = x),
Disposable.Create(() => scrollable.InvalidateScroll = null)); Disposable.Create(() => scrollable.InvalidateScroll = null));
UpdateFromScrollable(scrollable); UpdateFromScrollable(scrollable);
} }

10
src/Avalonia.Controls/Primitives/ILogicalScrollable.cs

@ -19,6 +19,16 @@ namespace Avalonia.Controls.Primitives
/// </remarks> /// </remarks>
public interface ILogicalScrollable : IScrollable public interface ILogicalScrollable : IScrollable
{ {
/// <summary>
/// Gets or sets a value indicating whether the content can be scrolled horizontally.
/// </summary>
bool CanHorizontallyScroll { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the content can be scrolled horizontally.
/// </summary>
bool CanVerticallyScroll { get; set; }
/// <summary> /// <summary>
/// Gets a value indicating whether logical scrolling is enabled on the control. /// Gets a value indicating whether logical scrolling is enabled on the control.
/// </summary> /// </summary>

1
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -99,6 +99,7 @@ namespace Avalonia.Controls.Primitives
case ScrollBarVisibility.Visible: case ScrollBarVisibility.Visible:
return true; return true;
case ScrollBarVisibility.Disabled:
case ScrollBarVisibility.Hidden: case ScrollBarVisibility.Hidden:
return false; return false;

3
src/Avalonia.Controls/Primitives/ScrollBarVisibility.cs

@ -5,8 +5,9 @@ namespace Avalonia.Controls.Primitives
{ {
public enum ScrollBarVisibility public enum ScrollBarVisibility
{ {
Disabled,
Auto, Auto,
Visible,
Hidden, Hidden,
Visible,
} }
} }

97
src/Avalonia.Controls/ScrollViewer.cs

@ -2,8 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System; using System;
using System.Linq;
using System.Reactive.Linq;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
@ -15,16 +13,34 @@ namespace Avalonia.Controls
public class ScrollViewer : ContentControl, IScrollable public class ScrollViewer : ContentControl, IScrollable
{ {
/// <summary> /// <summary>
/// Defines the <see cref="CanScrollHorizontally"/> property. /// Defines the <see cref="CanHorizontallyScroll"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<bool> CanScrollHorizontallyProperty = /// <remarks>
AvaloniaProperty.Register<ScrollViewer, bool>(nameof(CanScrollHorizontally), true); /// There is no public C# accessor for this property as it is intended to be bound to by a
/// <see cref="ScrollContentPresenter"/> in the control's template.
/// </remarks>
public static readonly DirectProperty<ScrollViewer, bool> CanHorizontallyScrollProperty =
AvaloniaProperty.RegisterDirect<ScrollViewer, bool>(
nameof(CanHorizontallyScroll),
o => o.CanHorizontallyScroll);
/// <summary>
/// Defines the <see cref="CanVerticallyScroll"/> property.
/// </summary>
/// <remarks>
/// There is no public C# accessor for this property as it is intended to be bound to by a
/// <see cref="ScrollContentPresenter"/> in the control's template.
/// </remarks>
public static readonly DirectProperty<ScrollViewer, bool> CanVerticallyScrollProperty =
AvaloniaProperty.RegisterDirect<ScrollViewer, bool>(
nameof(CanVerticallyScroll),
o => o.CanVerticallyScroll);
/// <summary> /// <summary>
/// Defines the <see cref="Extent"/> property. /// Defines the <see cref="Extent"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<ScrollViewer, Size> ExtentProperty = public static readonly DirectProperty<ScrollViewer, Size> ExtentProperty =
AvaloniaProperty.RegisterDirect<ScrollViewer, Size>(nameof(Extent), AvaloniaProperty.RegisterDirect<ScrollViewer, Size>(nameof(Extent),
o => o.Extent, o => o.Extent,
(o, v) => o.Extent = v); (o, v) => o.Extent = v);
@ -41,7 +57,7 @@ namespace Avalonia.Controls
/// Defines the <see cref="Viewport"/> property. /// Defines the <see cref="Viewport"/> property.
/// </summary> /// </summary>
public static readonly DirectProperty<ScrollViewer, Size> ViewportProperty = public static readonly DirectProperty<ScrollViewer, Size> ViewportProperty =
AvaloniaProperty.RegisterDirect<ScrollViewer, Size>(nameof(Viewport), AvaloniaProperty.RegisterDirect<ScrollViewer, Size>(nameof(Viewport),
o => o.Viewport, o => o.Viewport,
(o, v) => o.Viewport = v); (o, v) => o.Viewport = v);
@ -85,14 +101,10 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Defines the <see cref="HorizontalScrollBarVisibility"/> property. /// Defines the <see cref="HorizontalScrollBarVisibility"/> property.
/// </summary> /// </summary>
/// <remarks>
/// There is no public C# accessor for this property as it is intended to be bound to by a
/// <see cref="ScrollContentPresenter"/> in the control's template.
/// </remarks>
public static readonly AttachedProperty<ScrollBarVisibility> HorizontalScrollBarVisibilityProperty = public static readonly AttachedProperty<ScrollBarVisibility> HorizontalScrollBarVisibilityProperty =
AvaloniaProperty.RegisterAttached<ScrollViewer, Control, ScrollBarVisibility>( AvaloniaProperty.RegisterAttached<ScrollViewer, Control, ScrollBarVisibility>(
nameof(HorizontalScrollBarVisibility), nameof(HorizontalScrollBarVisibility),
ScrollBarVisibility.Auto); ScrollBarVisibility.Hidden);
/// <summary> /// <summary>
/// Defines the VerticalScrollBarMaximum property. /// Defines the VerticalScrollBarMaximum property.
@ -136,7 +148,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
public static readonly AttachedProperty<ScrollBarVisibility> VerticalScrollBarVisibilityProperty = public static readonly AttachedProperty<ScrollBarVisibility> VerticalScrollBarVisibilityProperty =
AvaloniaProperty.RegisterAttached<ScrollViewer, Control, ScrollBarVisibility>( AvaloniaProperty.RegisterAttached<ScrollViewer, Control, ScrollBarVisibility>(
nameof(VerticalScrollBarVisibility), nameof(VerticalScrollBarVisibility),
ScrollBarVisibility.Auto); ScrollBarVisibility.Auto);
private Size _extent; private Size _extent;
@ -150,6 +162,8 @@ namespace Avalonia.Controls
{ {
AffectsValidation(ExtentProperty, OffsetProperty); AffectsValidation(ExtentProperty, OffsetProperty);
AffectsValidation(ViewportProperty, OffsetProperty); AffectsValidation(ViewportProperty, OffsetProperty);
HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged);
VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged);
} }
/// <summary> /// <summary>
@ -218,15 +232,6 @@ namespace Avalonia.Controls
} }
} }
/// <summary>
/// Gets a value indicating whether the content can be scrolled horizontally.
/// </summary>
public bool CanScrollHorizontally
{
get { return GetValue(CanScrollHorizontallyProperty); }
set { SetValue(CanScrollHorizontallyProperty, value); }
}
/// <summary> /// <summary>
/// Gets or sets the horizontal scrollbar visibility. /// Gets or sets the horizontal scrollbar visibility.
/// </summary> /// </summary>
@ -245,6 +250,22 @@ namespace Avalonia.Controls
set { SetValue(VerticalScrollBarVisibilityProperty, value); } set { SetValue(VerticalScrollBarVisibilityProperty, value); }
} }
/// <summary>
/// Gets a value indicating whether the viewer can scroll horizontally.
/// </summary>
protected bool CanHorizontallyScroll
{
get { return HorizontalScrollBarVisibility != ScrollBarVisibility.Disabled; }
}
/// <summary>
/// Gets a value indicating whether the viewer can scroll vertically.
/// </summary>
protected bool CanVerticallyScroll
{
get { return VerticalScrollBarVisibility != ScrollBarVisibility.Disabled; }
}
/// <summary> /// <summary>
/// Gets the maximum horizontal scrollbar value. /// Gets the maximum horizontal scrollbar value.
/// </summary> /// </summary>
@ -316,7 +337,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="control">The control to read the value from.</param> /// <param name="control">The control to read the value from.</param>
/// <returns>The value of the property.</returns> /// <returns>The value of the property.</returns>
public ScrollBarVisibility GetHorizontalScrollBarVisibility(Control control) public static ScrollBarVisibility GetHorizontalScrollBarVisibility(Control control)
{ {
return control.GetValue(HorizontalScrollBarVisibilityProperty); return control.GetValue(HorizontalScrollBarVisibilityProperty);
} }
@ -326,7 +347,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="control">The control to set the value on.</param> /// <param name="control">The control to set the value on.</param>
/// <param name="value">The value of the property.</param> /// <param name="value">The value of the property.</param>
public void SetHorizontalScrollBarVisibility(Control control, ScrollBarVisibility value) public static void SetHorizontalScrollBarVisibility(Control control, ScrollBarVisibility value)
{ {
control.SetValue(HorizontalScrollBarVisibilityProperty, value); control.SetValue(HorizontalScrollBarVisibilityProperty, value);
} }
@ -336,7 +357,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="control">The control to read the value from.</param> /// <param name="control">The control to read the value from.</param>
/// <returns>The value of the property.</returns> /// <returns>The value of the property.</returns>
public ScrollBarVisibility GetVerticalScrollBarVisibility(Control control) public static ScrollBarVisibility GetVerticalScrollBarVisibility(Control control)
{ {
return control.GetValue(VerticalScrollBarVisibilityProperty); return control.GetValue(VerticalScrollBarVisibilityProperty);
} }
@ -346,7 +367,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
/// <param name="control">The control to set the value on.</param> /// <param name="control">The control to set the value on.</param>
/// <param name="value">The value of the property.</param> /// <param name="value">The value of the property.</param>
public void SetVerticalScrollBarVisibility(Control control, ScrollBarVisibility value) public static void SetVerticalScrollBarVisibility(Control control, ScrollBarVisibility value)
{ {
control.SetValue(VerticalScrollBarVisibilityProperty, value); control.SetValue(VerticalScrollBarVisibilityProperty, value);
} }
@ -385,6 +406,30 @@ namespace Avalonia.Controls
} }
} }
private void ScrollBarVisibilityChanged(AvaloniaPropertyChangedEventArgs e)
{
var wasEnabled = !ScrollBarVisibility.Disabled.Equals(e.OldValue);
var isEnabled = !ScrollBarVisibility.Disabled.Equals(e.NewValue);
if (wasEnabled != isEnabled)
{
if (e.Property == HorizontalScrollBarVisibilityProperty)
{
RaisePropertyChanged(
CanHorizontallyScrollProperty,
wasEnabled,
isEnabled);
}
else if (e.Property == VerticalScrollBarVisibilityProperty)
{
RaisePropertyChanged(
CanVerticallyScrollProperty,
wasEnabled,
isEnabled);
}
}
}
private void CalculatedPropertiesChanged() private void CalculatedPropertiesChanged()
{ {
// Pass old values of 0 here because we don't have the old values at this point, // Pass old values of 0 here because we don't have the old values at this point,

22
src/Avalonia.Controls/TextBox.cs

@ -8,7 +8,6 @@ using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Controls.Utils; using Avalonia.Controls.Utils;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -26,9 +25,6 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> AcceptsTabProperty = public static readonly StyledProperty<bool> AcceptsTabProperty =
AvaloniaProperty.Register<TextBox, bool>(nameof(AcceptsTab)); AvaloniaProperty.Register<TextBox, bool>(nameof(AcceptsTab));
public static readonly DirectProperty<TextBox, bool> CanScrollHorizontallyProperty =
AvaloniaProperty.RegisterDirect<TextBox, bool>(nameof(CanScrollHorizontally), o => o.CanScrollHorizontally);
public static readonly DirectProperty<TextBox, int> CaretIndexProperty = public static readonly DirectProperty<TextBox, int> CaretIndexProperty =
AvaloniaProperty.RegisterDirect<TextBox, int>( AvaloniaProperty.RegisterDirect<TextBox, int>(
nameof(CaretIndex), nameof(CaretIndex),
@ -92,7 +88,6 @@ namespace Avalonia.Controls
private int _caretIndex; private int _caretIndex;
private int _selectionStart; private int _selectionStart;
private int _selectionEnd; private int _selectionEnd;
private bool _canScrollHorizontally;
private TextPresenter _presenter; private TextPresenter _presenter;
private UndoRedoHelper<UndoRedoState> _undoRedoHelper; private UndoRedoHelper<UndoRedoState> _undoRedoHelper;
private bool _ignoreTextChanges; private bool _ignoreTextChanges;
@ -106,12 +101,11 @@ namespace Avalonia.Controls
public TextBox() public TextBox()
{ {
this.GetObservable(TextWrappingProperty) var horizontalScrollBarVisibility = Observable.CombineLatest(
.Select(x => x == TextWrapping.NoWrap) this.GetObservable(AcceptsReturnProperty),
.Subscribe(x => CanScrollHorizontally = x); this.GetObservable(TextWrappingProperty),
(acceptsReturn, wrapping) => acceptsReturn && wrapping == TextWrapping.NoWrap ?
var horizontalScrollBarVisibility = this.GetObservable(AcceptsReturnProperty) ScrollBarVisibility.Auto : ScrollBarVisibility.Disabled);
.Select(x => x ? ScrollBarVisibility.Auto : ScrollBarVisibility.Hidden);
Bind( Bind(
ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollViewer.HorizontalScrollBarVisibilityProperty,
@ -132,12 +126,6 @@ namespace Avalonia.Controls
set { SetValue(AcceptsTabProperty, value); } set { SetValue(AcceptsTabProperty, value); }
} }
public bool CanScrollHorizontally
{
get { return _canScrollHorizontally; }
private set { SetAndRaise(CanScrollHorizontallyProperty, ref _canScrollHorizontally, value); }
}
public int CaretIndex public int CaretIndex
{ {
get get

2
src/Avalonia.Controls/VirtualizingStackPanel.cs

@ -3,11 +3,9 @@
using System; using System;
using System.Collections.Specialized; using System.Collections.Specialized;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.VisualTree;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {

7
src/Avalonia.Themes.Default/ListBox.xaml

@ -3,11 +3,16 @@
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/> <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}"/>
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/> <Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}"/>
<Setter Property="Padding" Value="4"/> <Setter Property="Padding" Value="4"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" <Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Name="PART_ScrollViewer" Background="{TemplateBinding Background}"> <ScrollViewer Name="PART_ScrollViewer"
Background="{TemplateBinding Background}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}" ItemsPanel="{TemplateBinding ItemsPanel}"

5
src/Avalonia.Themes.Default/ScrollViewer.xaml

@ -6,12 +6,13 @@
<Grid ColumnDefinitions="*,Auto" RowDefinitions="*,Auto"> <Grid ColumnDefinitions="*,Auto" RowDefinitions="*,Auto">
<ScrollContentPresenter Name="PART_ContentPresenter" <ScrollContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
CanHorizontallyScroll="{TemplateBinding CanHorizontallyScroll}"
CanVerticallyScroll="{TemplateBinding CanVerticallyScroll}"
Content="{TemplateBinding Content}" Content="{TemplateBinding Content}"
Extent="{TemplateBinding Path=Extent, Mode=TwoWay}" Extent="{TemplateBinding Path=Extent, Mode=TwoWay}"
Margin="{TemplateBinding Padding}" Margin="{TemplateBinding Padding}"
Offset="{TemplateBinding Path=Offset, Mode=TwoWay}" Offset="{TemplateBinding Path=Offset, Mode=TwoWay}"
Viewport="{TemplateBinding Path=Viewport, Mode=TwoWay}" Viewport="{TemplateBinding Path=Viewport, Mode=TwoWay}"/>
CanScrollHorizontally="{TemplateBinding CanScrollHorizontally}"/>
<ScrollBar Name="horizontalScrollBar" <ScrollBar Name="horizontalScrollBar"
Orientation="Horizontal" Orientation="Horizontal"
Maximum="{TemplateBinding HorizontalScrollBarMaximum}" Maximum="{TemplateBinding HorizontalScrollBarMaximum}"

3
src/Avalonia.Themes.Default/TextBox.xaml

@ -36,8 +36,7 @@
<Path Data="M14,7 A7,7 0 0,0 0,7 M0,7 A7,7 0 1,0 14,7 M7,3l0,5 M7,9l0,2" Stroke="{DynamicResource ErrorBrush}" StrokeThickness="2"/> <Path Data="M14,7 A7,7 0 0,0 0,7 M0,7 A7,7 0 1,0 14,7 M7,3l0,5 M7,9l0,2" Stroke="{DynamicResource ErrorBrush}" StrokeThickness="2"/>
</Canvas> </Canvas>
<ScrollViewer CanScrollHorizontally="{TemplateBinding CanScrollHorizontally}" <ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"> VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}">
<Panel> <Panel>

2
src/Avalonia.Themes.Default/TreeView.xaml

@ -7,7 +7,7 @@
<ControlTemplate> <ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" <Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"> BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer CanScrollHorizontally="True" Background="{TemplateBinding Background}"> <ScrollViewer Background="{TemplateBinding Background}">
<ItemsPresenter Name="PART_ItemsPresenter" <ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}" Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}" ItemsPanel="{TemplateBinding ItemsPanel}"

2
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

@ -281,6 +281,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = new TestScroller var scroller = new TestScroller
{ {
CanHorizontallyScroll = false,
CanVerticallyScroll = true,
Content = result = new TestItemsPresenter(useContainers) Content = result = new TestItemsPresenter(useContainers)
{ {
Items = items, Items = items,

2
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

@ -998,6 +998,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
var scroller = new TestScroller var scroller = new TestScroller
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = result = new TestItemsPresenter(useContainers) Content = result = new TestItemsPresenter(useContainers)
{ {
Items = items, Items = items,

11
tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Layout; using Avalonia.Layout;
using Xunit; using Xunit;
@ -118,6 +119,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
TestControl content; TestControl content;
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = content = new TestControl(), Content = content = new TestControl(),
}; };
@ -134,6 +137,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
Border content; Border content;
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = content = new Border Content = content = new Border
{ {
Width = 150, Width = 150,
@ -155,8 +160,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
var child = new TestControl(); var child = new TestControl();
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanVerticallyScroll = true,
Content = child, Content = child,
[ScrollContentPresenter.CanScrollHorizontallyProperty] = false,
}; };
target.UpdateChild(); target.UpdateChild();
@ -171,6 +176,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
var child = new TestControl(); var child = new TestControl();
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = child, Content = child,
}; };
@ -246,6 +253,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
Border border; Border border;
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Width = 100, Width = 100,
Height = 100, Height = 100,
Content = new Decorator Content = new Decorator

46
tests/Avalonia.Controls.UnitTests/Presenters/ScrollContentPresenterTests_ILogicalScrollable.cs

@ -13,7 +13,7 @@ namespace Avalonia.Controls.UnitTests
public class ScrollContentPresenterTests_ILogicalScrollable public class ScrollContentPresenterTests_ILogicalScrollable
{ {
[Fact] [Fact]
public void Measure_Should_Pass_Unchanged_Bounds_To_IScrollable() public void Measure_Should_Pass_Unchanged_Bounds_To_ILogicalScrollable()
{ {
var scrollable = new TestScrollable(); var scrollable = new TestScrollable();
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
@ -28,7 +28,7 @@ namespace Avalonia.Controls.UnitTests
} }
[Fact] [Fact]
public void Arrange_Should_Not_Offset_IScrollable_Bounds() public void Arrange_Should_Not_Offset_ILogicalScrollable_Bounds()
{ {
var scrollable = new TestScrollable var scrollable = new TestScrollable
{ {
@ -50,7 +50,7 @@ namespace Avalonia.Controls.UnitTests
} }
[Fact] [Fact]
public void Arrange_Should_Offset_IScrollable_Bounds_When_Logical_Scroll_Disabled() public void Arrange_Should_Offset_ILogicalScrollable_Bounds_When_Logical_Scroll_Disabled()
{ {
var scrollable = new TestScrollable var scrollable = new TestScrollable
{ {
@ -59,6 +59,8 @@ namespace Avalonia.Controls.UnitTests
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = scrollable, Content = scrollable,
Offset = new Vector(25, 25), Offset = new Vector(25, 25),
}; };
@ -71,7 +73,7 @@ namespace Avalonia.Controls.UnitTests
} }
[Fact] [Fact]
public void Arrange_Should_Not_Set_Viewport_And_Extent_With_IScrollable() public void Arrange_Should_Not_Set_Viewport_And_Extent_With_ILogicalScrollable()
{ {
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
@ -122,7 +124,7 @@ namespace Avalonia.Controls.UnitTests
} }
[Fact] [Fact]
public void Extent_Offset_And_Viewport_Should_Be_Read_From_IScrollable() public void Extent_Offset_And_Viewport_Should_Be_Read_From_ILogicalScrollable()
{ {
var scrollable = new TestScrollable var scrollable = new TestScrollable
{ {
@ -152,7 +154,7 @@ namespace Avalonia.Controls.UnitTests
} }
[Fact] [Fact]
public void Offset_Should_Be_Written_To_IScrollable() public void Offset_Should_Be_Written_To_ILogicalScrollable()
{ {
var scrollable = new TestScrollable var scrollable = new TestScrollable
{ {
@ -172,7 +174,7 @@ namespace Avalonia.Controls.UnitTests
} }
[Fact] [Fact]
public void Offset_Should_Not_Be_Written_To_IScrollable_After_Removal() public void Offset_Should_Not_Be_Written_To_ILogicalScrollable_After_Removal()
{ {
var scrollable = new TestScrollable var scrollable = new TestScrollable
{ {
@ -203,6 +205,8 @@ namespace Avalonia.Controls.UnitTests
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = scrollable, Content = scrollable,
}; };
@ -253,6 +257,8 @@ namespace Avalonia.Controls.UnitTests
var target = new ScrollContentPresenter var target = new ScrollContentPresenter
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = logicalScrollable, Content = logicalScrollable,
}; };
@ -286,12 +292,38 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new Rect(0, 0, 100, 100), logicalScrollable.Bounds); Assert.Equal(new Rect(0, 0, 100, 100), logicalScrollable.Bounds);
} }
[Fact]
public void Should_Set_ILogicalScrolable_CanHorizontallyScroll()
{
var logicalScrollable = new TestScrollable();
var target = new ScrollContentPresenter { Content = logicalScrollable };
target.UpdateChild();
Assert.False(logicalScrollable.CanHorizontallyScroll);
target.CanHorizontallyScroll = true;
Assert.True(logicalScrollable.CanHorizontallyScroll);
}
[Fact]
public void Should_Set_ILogicalScrolable_CanVerticallyScroll()
{
var logicalScrollable = new TestScrollable();
var target = new ScrollContentPresenter { Content = logicalScrollable };
target.UpdateChild();
Assert.False(logicalScrollable.CanVerticallyScroll);
target.CanVerticallyScroll = true;
Assert.True(logicalScrollable.CanVerticallyScroll);
}
private class TestScrollable : Control, ILogicalScrollable private class TestScrollable : Control, ILogicalScrollable
{ {
private Size _extent; private Size _extent;
private Vector _offset; private Vector _offset;
private Size _viewport; private Size _viewport;
public bool CanHorizontallyScroll { get; set; }
public bool CanVerticallyScroll { get; set; }
public bool IsLogicalScrollEnabled { get; set; } = true; public bool IsLogicalScrollEnabled { get; set; } = true;
public Size AvailableSize { get; private set; } public Size AvailableSize { get; private set; }
public Action InvalidateScroll { get; set; } public Action InvalidateScroll { get; set; }

30
tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs

@ -1,6 +1,8 @@
// Copyright (c) The Avalonia Project. All rights reserved. // Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
@ -25,6 +27,32 @@ namespace Avalonia.Controls.UnitTests
Assert.IsType<TextBlock>(target.Presenter.Child); Assert.IsType<TextBlock>(target.Presenter.Child);
} }
[Fact]
public void CanHorizontallyScroll_Should_Track_HorizontalScrollBarVisibility()
{
var target = new ScrollViewer();
var values = new List<bool>();
target.GetObservable(ScrollViewer.CanHorizontallyScrollProperty).Subscribe(x => values.Add(x));
target.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
target.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
Assert.Equal(new[] { true, false, true }, values);
}
[Fact]
public void CanVerticallyScroll_Should_Track_VerticalScrollBarVisibility()
{
var target = new ScrollViewer();
var values = new List<bool>();
target.GetObservable(ScrollViewer.CanVerticallyScrollProperty).Subscribe(x => values.Add(x));
target.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
target.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
Assert.Equal(new[] { true, false, true }, values);
}
[Fact] [Fact]
public void Offset_Should_Be_Coerced_To_Viewport() public void Offset_Should_Be_Coerced_To_Viewport()
{ {
@ -59,7 +87,7 @@ namespace Avalonia.Controls.UnitTests
[~~ScrollContentPresenter.ExtentProperty] = control[~~ScrollViewer.ExtentProperty], [~~ScrollContentPresenter.ExtentProperty] = control[~~ScrollViewer.ExtentProperty],
[~~ScrollContentPresenter.OffsetProperty] = control[~~ScrollViewer.OffsetProperty], [~~ScrollContentPresenter.OffsetProperty] = control[~~ScrollViewer.OffsetProperty],
[~~ScrollContentPresenter.ViewportProperty] = control[~~ScrollViewer.ViewportProperty], [~~ScrollContentPresenter.ViewportProperty] = control[~~ScrollViewer.ViewportProperty],
[~ScrollContentPresenter.CanScrollHorizontallyProperty] = control[~ScrollViewer.CanScrollHorizontallyProperty], [~ScrollContentPresenter.CanHorizontallyScrollProperty] = control[~ScrollViewer.CanHorizontallyScrollProperty],
}, },
new ScrollBar new ScrollBar
{ {

2
tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs

@ -85,7 +85,7 @@ namespace Avalonia.Layout.UnitTests
{ {
Width = 200, Width = 200,
Height = 200, Height = 200,
CanScrollHorizontally = true, HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
HorizontalAlignment = HorizontalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center, VerticalAlignment = VerticalAlignment.Center,
Content = textBlock = new TextBlock Content = textBlock = new TextBlock

2
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests_HitTesting.cs

@ -372,6 +372,8 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Margin = new Thickness(0, 100, 0, 0), Margin = new Thickness(0, 100, 0, 0),
Child = scroll = new ScrollContentPresenter() Child = scroll = new ScrollContentPresenter()
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = new StackPanel() Content = new StackPanel()
{ {
Children = Children =

2
tests/Avalonia.Visuals.UnitTests/Rendering/ImmediateRendererTests_HitTesting.cs

@ -357,6 +357,8 @@ namespace Avalonia.Visuals.UnitTests.Rendering
Margin = new Thickness(0, 100, 0, 0), Margin = new Thickness(0, 100, 0, 0),
Child = scroll = new ScrollContentPresenter() Child = scroll = new ScrollContentPresenter()
{ {
CanHorizontallyScroll = true,
CanVerticallyScroll = true,
Content = new StackPanel() Content = new StackPanel()
{ {
Children = Children =

Loading…
Cancel
Save