I have ScrollViewer
that contain ItemsRepeater
of images and I want to bind in TextBox
the current index page of ItemsRepeater
when scroll the images.
this is my .xaml code:
<StackPanel Orientation="Horizontal">
<TextBlock>
<Run Text="{x:Bind ViewModel.Pages.Count, Mode=OneWay}"/>
<Run Text=" / "/>
</TextBlock>
<TextBox Text="{x:Bind ViewModel.PageIndex, Mode=TwoWay}" LostFocus="PageIndexTextBox_LostFocus" x:Name="PageIndexTextBox" InputScope="Number"/>
</StackPanel>
<ScrollViewer x:Name="scroll" ZoomMode="Enabled" Grid.Row="1"
IsTabStop="True" IsVerticalScrollChainingEnabled="True"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Hidden"
VerticalScrollMode="Enabled" VerticalScrollBarVisibility="Auto"
ViewChanged="ScrollViewer_ViewChanged">
<ItemsRepeater ItemsSource="{x:Bind ViewModel.Pages, Mode=OneWay}"
MaxWidth="{Binding ElementName=scroll, Path=ActualWidth}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:Name="PdfImageRepeater">
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="pdfImage:PdfImage">
<Grid Padding="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Image Source="{x:Bind Image, Mode=OneWay}" Stretch="Uniform"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
<ItemsRepeater.Layout>
<StackLayout Orientation="Vertical"/>
</ItemsRepeater.Layout>
</ItemsRepeater>
</ScrollViewer>
And this is in my .xaml.cs code:
private void PageIndexTextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (int.TryParse(PageIndexTextBox.Text, out int pageIndex))
{
pageIndex -= 1;
if (pageIndex >= 0 && pageIndex < ViewModel.Pages.Count)
{
var pageItem = PdfImageRepeater.GetOrCreateElement(pageIndex);
pageItem.UpdateLayout();
pageItem.StartBringIntoView();
}
}
}
How can I add option to display index of current ScrollViewr
page in WinUI 3 ?
If you can fix the height of the items, for example:
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="local:Member">
<Grid
MinHeight="50"
MaxHeight="50">
<!-- Item Content -->
</Grid>
</DataTemplate x:DataType="local:Member">
</ItemsRepeater.ItemTemplate>
you can do something like this:
private ScrollBar? VerticalScrollBar { get; set; }
private void ItemsRepeaterScrollViewer_Loaded(object sender, RoutedEventArgs e)
{
if (sender is not ScrollViewer scrollViewer ||
scrollViewer.FindDescendant<ScrollBar>(x => x.Orientation is Orientation.Vertical) is not ScrollBar verticalScrollBar)
{
return;
}
VerticalScrollBar = verticalScrollBar;
VerticalScrollBar.ValueChanged += VerticalScrollBar_ValueChanged;
}
private void VerticalScrollBar_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
MemberIndexNumberBox.Value = Math.Round(e.NewValue / 50);
}
private void MemberIndexNumberBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
{
if (VerticalScrollBar is null)
{
return;
}
ItemsRepeaterScrollViewer.ScrollToVerticalOffset(args.NewValue * 50);
}
The FindDescendant extension comes from the CommunityToolkit.WinUI.Extensions NuGet package.