Skip to content

Commit

Permalink
Add listview and repeater examples to PipsPager (#3789)
Browse files Browse the repository at this point in the history
* Add listview and repeater examples for PipsPager
  • Loading branch information
beervoley authored Jan 8, 2021
1 parent 8620603 commit 2c6f199
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 28 deletions.
206 changes: 206 additions & 0 deletions dev/PipsPager/TestUI/PipsPagerExamples.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<Page
x:Class="MUXControlsTestApp.PipsPagerExamples"
x:Name="PipsPagerExamplesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:MUXControlsTestApp"
xmlns:Windows10FallCreatorsUpdate="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 5)"
mc:Ignorable="d">

<Page.Resources>
<ResourceDictionary>
<Style x:Key="NavButtonBaseStyle" TargetType="Button" BasedOn="{StaticResource NavigatonButtonBaseStyle}">
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="FontSize" Value="12" />
</Style>

<Style x:Key="PreviousButtonStyle" BasedOn="{StaticResource NavButtonBaseStyle}" TargetType="Button">
<Setter Property="Content" Value="{StaticResource PipsPagerPreviousPageButtonGlyph}" />
</Style>

<Style x:Key="NextButtonStyle" BasedOn="{StaticResource NavButtonBaseStyle}" TargetType="Button">
<Setter Property="Content" Value="{StaticResource PipsPagerNextPageButtonGlyph}" />
</Style>

<Style x:Key="BasePipStyle" TargetType="Button" BasedOn="{StaticResource PipsPagerButtonBaseStyle}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FontFamily" Value="{StaticResource SymbolThemeFontFamily}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button" >
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PipsPagerPageNavigationButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PipsPagerPageNavigationButtonForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="#545454" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<FontIcon
x:Name="Content"
FontSize="{TemplateBinding FontSize}"
FontFamily="{TemplateBinding FontFamily}"
Glyph="{TemplateBinding Content}"
MirroredWhenRightToLeft="True"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style x:Key="SelectedPipStyle" BasedOn="{StaticResource BasePipStyle}" TargetType="Button">
<Setter Property="Content" Value="{StaticResource PipsPagerSelectedGlyph}" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="#545454" />
</Style>

<Style x:Key="DefaultPipStyle" BasedOn="{StaticResource BasePipStyle}" TargetType="Button">
<Setter Property="Content" Value="{StaticResource PipsPagerDefaultGlyph}" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="#CDCDCD" />
</Style>
</ResourceDictionary>
</Page.Resources>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="100" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<StackPanel Windows10FallCreatorsUpdate:Spacing="20">
<TextBlock Text="ListView Example" FontSize="20"
HorizontalAlignment="Center"
VerticalAlignment="Top" />

<ListView x:Name="PersonInfoList" MaxHeight="210">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:PersonInfo">
<StackPanel Orientation="Horizontal" Margin="0, 10, 0, 10" Windows10FallCreatorsUpdate:Spacing="10">
<controls:PersonPicture
MaxHeight="50"
MaxWidth="100"
DisplayName="{x:Bind FullName}"
Initials="{x:Bind Initials}" />
<TextBlock Text="{x:Bind FullName}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>

<controls:PipsPager x:Name="PersonInfoListPager"
Margin="50, 0, 0, 0"
VerticalAlignment="Center"
AutomationProperties.Name="ListViewPager"
Orientation="Vertical" PreviousButtonVisibility="Visible" NextButtonVisibility="Visible" Grid.Column="1"
PreviousButtonStyle="{StaticResource PreviousButtonStyle}"
NextButtonStyle="{StaticResource NextButtonStyle}"
DefaultIndicatorButtonStyle="{StaticResource DefaultPipStyle}"
SelectedIndicatorButtonStyle="{StaticResource SelectedPipStyle}"
SelectedIndexChanged="PersonInfoListPager_SelectedIndexChanged" />

<StackPanel Windows10FallCreatorsUpdate:Spacing="20" Grid.Row="2">
<TextBlock Text="ItemsRepeater Example" FontSize="20"
HorizontalAlignment="Center" VerticalAlignment="Top" />

<ScrollViewer x:Name="ButtonListScrollViewer" Width="250" Height="224"
ViewChanged="ButtonListScrollViewer_ViewChanged">
<controls:ItemsRepeater x:Name="ButtonListRepeater" VerticalCacheLength="4">
<controls:ItemsRepeater.Layout>
<controls:UniformGridLayout
MinRowSpacing="{x:Bind MinRowSpacing}"
MinColumnSpacing="8"
Orientation="Horizontal"
ItemsJustification="Start"
ItemsStretch="None" />
</controls:ItemsRepeater.Layout>
<controls:ItemsRepeater.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding}" Width="50" Height="50" />
</StackPanel>
</DataTemplate>
</controls:ItemsRepeater.ItemTemplate>
</controls:ItemsRepeater>
</ScrollViewer>
</StackPanel>

<controls:PipsPager x:Name="ButtonListPager" Grid.Row="2" Grid.Column="1"
Margin="50, 0, 0, 0"
VerticalAlignment="Center"
AutomationProperties.Name="ItemsRepeaterPager"
Orientation="Vertical" PreviousButtonVisibility="VisibleOnHover" NextButtonVisibility="VisibleOnHover"
PreviousButtonStyle="{StaticResource PreviousButtonStyle}"
NextButtonStyle="{StaticResource NextButtonStyle}"
DefaultIndicatorButtonStyle="{StaticResource DefaultPipStyle}"
SelectedIndicatorButtonStyle="{StaticResource SelectedPipStyle}"
SelectedIndexChanged="ButtonListPager_SelectedIndexChanged" />

<StackPanel Windows10FallCreatorsUpdate:Spacing="20" Grid.Column="3">
<TextBlock Text="FlipView Example" FontSize="20"
HorizontalAlignment="Center" VerticalAlignment="Top" />

<FlipView x:Name="Gallery" Width="250" Height="250" ItemsSource="{x:Bind Pictures}">
<FlipView.ItemTemplate>
<DataTemplate>
<Grid>
<Image Source="{Binding}" Stretch="UniformToFill" />
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</StackPanel>

<controls:PipsPager x:Name="FlipViewPipsPager"
Margin="50, 0, 0, 0"
Grid.Column="4"
VerticalAlignment="Center"
NumberOfPages="{x:Bind Pictures.Count}"
AutomationProperties.Name="FlipViewPipsPager"
NextButtonVisibility="VisibleOnHover"
PreviousButtonVisibility="VisibleOnHover"
PreviousButtonStyle="{StaticResource PreviousButtonStyle}"
NextButtonStyle="{StaticResource NextButtonStyle}"
DefaultIndicatorButtonStyle="{StaticResource DefaultPipStyle}"
SelectedIndicatorButtonStyle="{StaticResource SelectedPipStyle}"
SelectedPageIndex="{Binding ElementName=Gallery, Path=SelectedIndex, Mode=TwoWay}" />
</Grid>
</Page>
150 changes: 150 additions & 0 deletions dev/PipsPager/TestUI/PipsPagerExamples.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
using System;
using Windows.UI.Xaml.Controls;
using System.Collections.Generic;
using System.Linq;
using PipsPagerSelectedIndexChangedEventArgs = Microsoft.UI.Xaml.Controls.PipsPagerSelectedIndexChangedEventArgs;
using PipsPager = Microsoft.UI.Xaml.Controls.PipsPager;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using System.Collections.ObjectModel;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Foundation;

namespace MUXControlsTestApp
{
public sealed partial class PipsPagerExamples : Page
{
private int MinRowSpacing = 8;
private int TotalNumberOfDisplayedObjects = 50;
private double ButtonListPreviousOffset = 0.0;
private double PersonInfoListPreviousOffset = 0.0;
private ScrollViewer PersonInfoListScrollViewer;
public List<string> Pictures = new List<string>()
{

"Assets/ingredient1.png",
"Assets/ingredient2.png",
"Assets/ingredient3.png",
"Assets/ingredient4.png",
"Assets/ingredient5.png",
"Assets/ingredient6.png",
"Assets/ingredient7.png",
"Assets/ingredient8.png",
};

public PipsPagerExamples()
{
this.InitializeComponent();
PersonInfoList.ItemsSource = CreatePersonInfoList();
ButtonListRepeater.ItemsSource = CreateButtonListItems();
this.Loaded += OnLoaded;
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
ButtonListPager.NumberOfPages = (int)Math.Ceiling(ButtonListScrollViewer.ExtentHeight / ButtonListScrollViewer.ViewportHeight);
SetButtonListRepeaterSize();
PersonInfoListScrollViewer = FindInnerScrollViewer(PersonInfoList);
PersonInfoListScrollViewer.ViewChanged += PersonInfoList_ViewChanged;
PersonInfoListPager.NumberOfPages = (int)Math.Ceiling(PersonInfoListScrollViewer.ExtentHeight / PersonInfoListScrollViewer.ViewportHeight);
}

private void SetButtonListRepeaterSize()
{
DataTemplate dt = ButtonListRepeater.ItemTemplate as DataTemplate;
Image img = VisualTreeHelper.GetChild(dt.LoadContent() as StackPanel, 0) as Image;
img.Source = new BitmapImage(new Uri("ms-appx:/Assets/ingredient1.png"));
img.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var numberOfPages = (int)Math.Ceiling(ButtonListScrollViewer.ExtentHeight / ButtonListScrollViewer.ViewportHeight);
ButtonListRepeater.Height = ButtonListScrollViewer.ViewportHeight * numberOfPages + MinRowSpacing * (numberOfPages - 1); ;
}

private void PersonInfoListPager_SelectedIndexChanged(PipsPager sender, PipsPagerSelectedIndexChangedEventArgs args)
{
if (PersonInfoListScrollViewer != null)
{
PersonInfoListScrollViewer.ChangeView(null, args.NewPageIndex * PersonInfoListScrollViewer.ViewportHeight, null);
}
}

private void PersonInfoList_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (!e.IsIntermediate)
{
OnViewChanged(PersonInfoListScrollViewer, PersonInfoListPager, ref PersonInfoListPreviousOffset);
}
}

private void ButtonListScrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
if (!e.IsIntermediate)
{
OnViewChanged(ButtonListScrollViewer, ButtonListPager, ref ButtonListPreviousOffset, MinRowSpacing);
}
}

private void ButtonListPager_SelectedIndexChanged(PipsPager sender, PipsPagerSelectedIndexChangedEventArgs args)
{
ButtonListScrollViewer.ChangeView(null, args.NewPageIndex * (ButtonListScrollViewer.ViewportHeight + MinRowSpacing), null);
}

private ObservableCollection<PersonInfo> CreatePersonInfoList()
{
ObservableCollection<PersonInfo> items = new ObservableCollection<PersonInfo>();
for (int i = 0; i < 15; i++)
{
items.Add(new PersonInfo($"RandomName{i}", $"RandomSurname{i}"));
}
return items;
}

private string[] CreateButtonListItems()
{
var rnd = new Random();
var items = new string[TotalNumberOfDisplayedObjects];
for (int i = 0; i < TotalNumberOfDisplayedObjects; i++)
{
items[i] = $"Assets/ingredient{rnd.Next(1, 100) % 4 + 1}.png";
}
return items;
}

private ScrollViewer FindInnerScrollViewer(ListView lv)
{
Panel p = lv.ItemsPanelRoot;
UIElement parent = VisualTreeHelper.GetParent(p) as UIElement;
while (parent != null && !(parent is ScrollViewer))
parent = VisualTreeHelper.GetParent(parent) as UIElement;

return parent as ScrollViewer;
}

private void OnViewChanged(ScrollViewer sv, PipsPager pager, ref double previousVerticalOffset, double rowSpacing = 0.0)
{
var newVerticalOffset = sv.VerticalOffset;

if (newVerticalOffset <= previousVerticalOffset)
{
pager.SelectedPageIndex = (int)Math.Floor(sv.VerticalOffset / (sv.ViewportHeight + rowSpacing));
}
else
{
pager.SelectedPageIndex = (int)Math.Ceiling(sv.VerticalOffset / (sv.ViewportHeight + rowSpacing));
}

previousVerticalOffset = newVerticalOffset;
}
}

public class PersonInfo
{
public PersonInfo(string name, string surname)
{
FullName = $"{name} {surname}";
Initials = $"{Char.ToUpper(name.ElementAtOrDefault(0))}{Char.ToUpper(surname.ElementAtOrDefault(0))}";
}

public string FullName { get; set; }
public string Initials { get; set; }
}
}
Loading

0 comments on commit 2c6f199

Please sign in to comment.