How to make circular / circular ScrollViewer in Windows 8 Metro (C ++ / XAML)

In a Windows 8 Metro app, can I create a ScrollViewer that, upon reaching the last element in the view, returns to the first element in the view? If so, how can I achieve this effect?

+6
source share
2 answers

It is definitely possible. I am solving the problem at the moment and will publish the work when it is done. So far, something like below.

The idea is that you hook into the viewchanged event for the scroll viewer, which fires anytime you move the panel. Sometime there, calculate where you are in the offset and size of your items, and then you can use this to measure against the actual size of your list container or what you have.

Once you know where you are in the budget, and know the actual height of your list and the height of your items, you know which items are currently visible and which are not. Make sure your list is linked to an object - this is an observable collection that implements a two-way INotifyChanged interface. You can then define a set of objects to rotate forward and backward based on where you are scrolling.

Another option is to try a different starting point, perhaps one control with a selection and a scroll bar below it?

Xaml

</UserControl.Resources> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ScrollViewer x:Name="ScrollViewer1"> <ListBox x:Name="SampleListBox" Background="White" ItemsSource="{Binding Path=sampleItems}" ItemTemplate="{StaticResource sampleTemplate}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="0" Grid.RowSpan="2"> </ListBox> </ScrollViewer> </Grid> 

Code for

  public sealed partial class MainPage : Page { List<SampleItem> sampleItems; const int numItems = 15; public MainPage() { sampleItems = new List<SampleItem>(); for (int i = 0; i < numItems; i++) { sampleItems.Add(new SampleItem(i)); } this.InitializeComponent(); SampleListBox.ItemsSource = sampleItems; ScrollViewer1.ViewChanged += ScrollViewer1_ViewChanged; } void ScrollViewer1_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { ScrollViewer viewer = sender as ScrollViewer; ListBox box = viewer.Content as ListBox; ListBoxItem lbi = box.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem; double elementSize; if (lbi == null) return; elementSize = lbi.ActualHeight; } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } } public class SampleItem { public String ItemCount { get; set; } public SampleItem(int itemCount) { ItemCount = itemCount.ToString(); } } 
+3
source

I do not believe that there is such a control in WinRT / XAML, so you will need to implement a custom control. There are many approaches that you could take, but I would probably avoid using ScrollViewer and handle the manipulation events directly, as it would not be easy to reduce the behavior of ScrollViewer to your requirements. I would control the scroll offset based on the manipulation events and based on the scroll shift - positioned the elements in the view - for example, using the Canvas control. You will need to move the items in the toolbox depending on the scroll offset, so that, for example, items that go beyond the view port at one end are moved to the other end. This will be related to custom dependency properties, product containers, etc. Perhaps at least a few hours of work if you know all of these APIs.

+1
source

Source: https://habr.com/ru/post/919754/


All Articles