Skip to content

Commit

Permalink
fix(scrollviewer): Fix ScrollViewer.ViewportWidth calculation
Browse files Browse the repository at this point in the history
ViewportWidth/Height should be based on the dimensions of ScrollContentPresenter, which can be smaller than the ScrollViewer in non-standard templates.
  • Loading branch information
davidjohnoliver committed Feb 3, 2021
1 parent cc97702 commit e87a198
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,27 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Private.Infrastructure;
using static Private.Infrastructure.TestServices;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Shapes;
using Windows.UI.Xaml.Media;
using Windows.UI;

namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls
{
[TestClass]
[RunsOnUIThread]
public class Given_ScrollViewer
{
private ResourceDictionary _testsResources;

public Style ScrollViewerCrowdedTemplateStyle => _testsResources["ScrollViewerCrowdedTemplateStyle"] as Style;

[TestInitialize]
public void Init()
{
_testsResources = new TestsResources();
}

#if __SKIA__ || __WASM__
[TestMethod]
public async Task When_CreateVerticalScroller_Then_DoNotLoadAllTemplate()
Expand Down Expand Up @@ -42,5 +56,36 @@ public async Task When_CreateVerticalScroller_Then_DoNotLoadAllTemplate()
Assert.IsTrue(buttons <= 4);
}
#endif

[TestMethod]
public async Task When_Presenter_Doesnt_Take_Up_All_Space()
{
const int ContentWidth = 700;
var content = new Ellipse
{
Width = ContentWidth,
VerticalAlignment = VerticalAlignment.Stretch,
Fill = new SolidColorBrush(Colors.Tomato)
};
const double ScrollViewerWidth = 300;
var SUT = new ScrollViewer
{
Style = ScrollViewerCrowdedTemplateStyle,
Width = ScrollViewerWidth,
Height = 200,
Content = content
};

WindowHelper.WindowContent = SUT;

await WindowHelper.WaitForLoaded(content);

const double ButtonWidth = 29;
const double PresenterActualWidth = ScrollViewerWidth - 2 * ButtonWidth;
Assert.AreEqual(PresenterActualWidth, SUT.ViewportWidth);
Assert.AreEqual(ContentWidth, SUT.ExtentWidth);
Assert.AreEqual(ContentWidth - PresenterActualWidth, SUT.ScrollableWidth);
;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,45 @@
<TextBlock Text="{Binding UserName}" />
</Grid>
</DataTemplate>
<Style x:Key="ScrollViewerCrowdedTemplateStyle"
TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility"
Value="Auto" />
<Setter Property="HorizontalScrollMode"
Value="Enabled" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<RepeatButton x:Name="ScrollDecreaseButton"
VerticalAlignment="Bottom"
Width="29"
Height="29"
Delay="50"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Interval="100"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Content="&#xE76B;" />
<ScrollContentPresenter x:Name="ScrollContentPresenter"
Grid.Column="1" />
<RepeatButton x:Name="ScrollIncreaseButton"
Grid.Column="2"
VerticalAlignment="Bottom"
Width="29"
Height="29"
Delay="50"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
Interval="100"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Content="&#xE76C;" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
5 changes: 3 additions & 2 deletions src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -672,8 +672,9 @@ private void UpdateDimensionProperties()
return;
}

ViewportHeight = ActualHeight;
ViewportWidth = ActualWidth;
// The dimensions of the presenter (which are often but not always the same as the ScrollViewer) determine the viewport size
ViewportHeight = (_presenter as IFrameworkElement)?.ActualHeight ?? ActualHeight;
ViewportWidth = (_presenter as IFrameworkElement)?.ActualWidth ?? ActualWidth;

ExtentHeight = (Content as IFrameworkElement)?.ActualHeight ?? 0;
ExtentWidth = (Content as IFrameworkElement)?.ActualWidth ?? 0;
Expand Down

0 comments on commit e87a198

Please sign in to comment.