0

我在滚动查看器内的堆栈面板中水平添加了 10 张图像。当用户滑动页面时,滚动查看器停止在某个位置,如果滚动停止在 2 个图像的中间,如下图所示的第一个图像,我想将编号为 3 的图像设置为自动滚动并适合左侧像第二张图片一样的屏幕

无标题

在此处输入图像描述

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

2 回答 2

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滚动到该位置。

于 2012-05-02T13:06:04.773 回答
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

于 2012-05-02T13:02:51.573 回答