滚动时停止滚动查看器内的堆栈面项目位于显示左侧

时间:2012-05-02 11:44:35

标签: windows-phone-7 silverlight-4.0 windows-phone-7.1

我在水平的堆叠面板中添加了10个图像,这些图像位于滚动查看器内部。当用户滑动页面时,滚动查看器停在某个位置,如果滚动停在2个图像的中间,如下图所示的第一个图像,我想设置数字3的图像,以自动滚动并适合左侧的屏幕就像在第二张图片中

untitled

enter image description here

for (int i = 0; i <= 9; i++)
{
    Uri uri = new  Uri("http://d1mu9ule1cy7bp.cloudfront.net//catalogues/47/pages/p_" + i + "/thump.jpg");
    ImageSource img1 = new BitmapImage(uri);
    Image rect = new Image { RenderTransform = new TranslateTransform() };

    rect.Source = img1;

    stack.Children.Add(rect);

}

XAML:

<Grid x:Name="LayoutRoot" Width="480" Background="Transparent" Margin="0,-33,0,0" Height="800">

 <ScrollViewer HorizontalContentAlignment="Left" HorizontalAlignment="Left" Name="scroll" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">

  <StackPanel Name="stack" Width="Auto" Orientation="Horizontal" HorizontalAlignment="Left"  >

</StackPanel>
</ScrollViewer>
</Grid>

2 个答案:

答案 0 :(得分:3)

您需要做的第一件事是检测哪个项目与屏幕的一侧重叠。为此,迭代StackPanel中的每个项目,并确定它们相对于屏幕上具有固定位置的其他元素的位置。

为此,我使用以下扩展方法:

/// <summary>
/// Gets the relative position of the given UIElement to this.
/// </summary>
public static Point GetRelativePosition(this UIElement element, UIElement other)
{
    return element.TransformToVisual(other)
                  .Transform(new Point(0, 0));
}

即。对于每个项目,请拨打以下内容;

Point position = stackPanelItem.GetRelativePosition(someFixedElement);

使用每个项目的位置,您应该能够找出哪个项目与屏幕重叠。

然后,您需要计算滚动所需的数量,以确保您的商品完全可见,然后使用ScrollViewer.ScrollToVerticalOffset滚动到该位置。

答案 1 :(得分:2)

这可能不是最好的解决方案,我相信有更好的方法可以达到这个目的,但你可以使用以下方法: -

XAML: -

    <ListBox x:Name="MyListBox"
            ScrollViewer.VerticalScrollBarVisibility="Disabled"
            ScrollViewer.HorizontalScrollBarVisibility="Visible">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

C#: -

    DispatcherTimer myTimer = new DispatcherTimer();

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        for (int i = 0; i < 10; i++)
        {
            MyListBox.Items.Add(new Button()
            {
                Content = i.ToString(),
                Width = 200,
                Height = 100,
            });

            MyListBox.MouseMove += new MouseEventHandler(MyListBox_MouseMove);
        }

        myTimer.Interval = TimeSpan.FromSeconds(1);
        myTimer.Tick += new EventHandler(myTimer_Tick);
    }

    private void myTimer_Tick(object sender, EventArgs e)
    {
        myTimer.Stop();

        SnapFirstItem();
    }       

    private void MyListBox_MouseMove(object sender, MouseEventArgs e)
    {
        myTimer.Stop();
        myTimer.Start();
    }

    private void SnapFirstItem()
    {
        foreach (Button currentButton in MyListBox.Items)
        {
            bool visible = MyListBox.TestVisibility(currentButton, System.Windows.Controls.Orientation.Horizontal, true);

            if (visible)
            {
                MyListBox.ScrollIntoView(currentButton);
                break;
            }
        }
    }

TestVisibility扩展方法来自以下方面: -

http://blogs.msdn.com/b/ptorr/archive/2010/10/12/procrastination-ftw-lazylistbox-should-improve-your-scrolling-performance-and-responsiveness.aspx