0

スクロールビューア内にあるスタックパネルに水平に10枚の画像を追加しました。ユーザーがページをスワイプすると、スクロールビューアが特定の位置で停止します。下に示す最初の画像のように、スクロールが2つの画像の途中で停止した場合、番号3の画像を自動的にスクロールして左側に合わせるように設定したい2番目の画像のような画面

無題

ここに画像の説明を入力

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 に答える