2012-05-02 12 views
0

スクロールビューア内の横にあるスタックパネルに10枚の画像を追加しました。ユーザーがページをスワイプすると、スクロールが特定の位置で停止します。スクロールが2つの画像の中間に停止すると、下の最初の画像のように停止します。番号3の画像を自動的にスクロールして、第2の画像内のような画面スクロールビューア内のスタックパネル項目をスクロール時のディスプレイ左側に停止する

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

これはおそらく最も素晴らしい解決策ではないと私はこれを達成するためのより良い方法があると確信していますが、次のように使用できます: -

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

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を使用してその位置にスクロールします。

+0

ここで述べた「その他」のUIElementは何ですか? –

+0

OK ... GetRelativePositionを使用すると、ある要素の位置を別の要素の位置から見つけることができます。 ScrollViewer内でスクロールするコンテンツがあるため、このスクロール領域外の他の要素を使用する必要があります。あなたはあなたの 'root'要素、すなわち 'Application.Current.RootVisual'を使用することができます – ColinE

+0

私はあなたのソリューションがこの問題を解決できることを願っています。しかし、初心者ですから、サンプルコードやサンプルコードをgothroughに送ってください。 –

関連する問題