C++ 如何在Windows 8 Metro(C+;+;/XAML)中制作循环/循环滚动查看器

C++ 如何在Windows 8 Metro(C+;+;/XAML)中制作循环/循环滚动查看器,c++,xaml,windows-8,windows-runtime,winrt-xaml,C++,Xaml,Windows 8,Windows Runtime,Winrt Xaml,在Windows 8 Metro应用程序中,是否可以创建一个ScrollViewer,在到达视图中的最后一个项目时,它会循环回视图中的第一个项目?如果是这样,我如何才能达到这种效果?我不相信WinRT/XAML中有这样的控件,所以您需要实现一个自定义控件。您可以采取很多方法,但我可能会避免使用ScrollViewer并直接处理操作事件,因为要使ScrollViewer的行为符合您的要求可能并不容易。我将根据操纵事件和滚动偏移控制滚动偏移-在视图中定位元素-例如,使用画布控件。您需要根据滚动偏移在

在Windows 8 Metro应用程序中,是否可以创建一个ScrollViewer,在到达视图中的最后一个项目时,它会循环回视图中的第一个项目?如果是这样,我如何才能达到这种效果?

我不相信WinRT/XAML中有这样的控件,所以您需要实现一个自定义控件。您可以采取很多方法,但我可能会避免使用ScrollViewer并直接处理操作事件,因为要使ScrollViewer的行为符合您的要求可能并不容易。我将根据操纵事件和滚动偏移控制滚动偏移-在视图中定位元素-例如,使用画布控件。您需要根据滚动偏移在“项目”面板中重新定位元素,以便将超出一端的项目移动到另一端。它将涉及自定义依赖项属性、项容器等。如果您了解所有这些API,可能至少需要几个小时的工作。

这绝对是可能的。我现在正在解决问题,完成后会发布工作。到目前为止,情况大致如下

</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>
这样做的想法是,您可以挂接到scroll viewer的viewchanged事件,该事件可以在您移动滚动条时触发。到达后,计算您在偏移量中的位置和项目的大小,然后您可以使用它来测量listbox容器的实际大小或您拥有的内容

</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>
一旦知道了偏移量中的位置,知道了列表框的实际高度和项目的高度,就可以知道哪些项目当前可见,哪些项目不可见。确保绑定到对象的列表是一个可观察的集合,通过双向绑定实现INotifyChanged接口。然后,您可以根据滚动的位置定义一组要来回旋转的对象

</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>
另一个选择是尝试不同的起点,也许是一个带有字幕和滚动条的单一控件

</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>
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>

</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>
代码隐藏

</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>
    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();
    }
}
公共密封部分类主页面:第页
{
列出抽样项目;
常数int numItems=15;
公共主页()
{
sampleItems=新列表();
对于(int i=0;i