2011-07-16 8 views
10

私は、カメラアプリの写真のストリップと非常によく似た効果を作り出すいくつかの問題にぶつかっています。WP7でCamera app style photo stripを実装する方法は?

私がしたいのは、それぞれが画面と同じ大きさのグリッドの行を表示することです(ポートレートかランドスケープかにかかわらず)。既に、私は何かをハッキーとアスペクト比を維持するためにcreate dependency properties that the grids width and height properties bind toをしなければならなかった。

これは問題なく動作します。しかし、私のストリップのためのStackPanelを作成し、ナビゲーションを実装する(または単にZ-インデックス変換でズームバックする)と、StackPanelが画面の大きさよりも大きく表示されないことがわかります(ちょうど1つのグリッドのサイズにクリップされます) 。私はこの問題を説明している投稿を見つけたと思ったが、今見つけられない。あなたがこの投稿について考えている投稿を知っている場合、またはこの制限についてもっと知っている場合は投稿してください。

私が見つけた唯一の回避策は、私が必要とする動作ではないScrollViewerを使用することですが、StackPanelを画面より広くすることができます。

実際の問題はScrollViewerの振る舞いです。自由にスクロールするのではなく、グリッドからグリッドに移動する必要があるため(写真ストリップのように)、Horizo​​ntalOffsetはアニメーション可能なプロパティではありません。私は15ミリ秒ごとにScrollToHorizo​​ntalOffsetを呼び出すことによってアニメーションを強制することができます。これは基本的に私自身のイージング効果を手動で実装することです。これは巨大なハックのように思えますが、その動作は非常に不思議です(私が期待するたびにManipulationCompletedイベントを取得しない - スワイプアクションの最後に - またはScrollViewerの慣性物理が私の効果を妨げている)。

私が遭遇した問題や、Silverlightのカメラ写真ストリップの体験を得るための全く別の方法について、誰かがより良い回避策を知っていますか?

私はPivotコントロールを使用することを検討しましたが、それは私が欲しいものではありません(次のアイテムが入る前に各アイテムを完全にアニメーション化したい場合は、それを達成するための制約の少ない方法)。もっと重要なのは、ストリップは、私が動的にやりたいと思っている多くの効果の1つに過ぎません。 CoolIrisのような3DチルトやFlipPadスタイルのページターンを交互にしたいと思います。現在の設定がうまく動作するようにすれば、これらの他のエフェクトを(テーマ変換として)簡単に実装できます。 Pivotのようなコントロールにコミットすると、私はそのビジョンに近づくことはありません。ここで

は私のXAMLです:

<Grid x:Name="LayoutRoot" Background="Transparent" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" HorizontalAlignment="Left" VerticalAlignment="Top"> 
     <ScrollViewer x:Name="SlideScroller" VerticalScrollBarVisibility="Disabled" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Margin="0,0,0,-31" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalAlignment="Left" VerticalAlignment="Top"> 
      <StackPanel x:Name="SlidePanel" Orientation="Horizontal" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left">  
       <Grid x:Name="Slide0" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC"> 
        <Image x:Name="Photo0" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/> 
       </Grid> 
       <Grid x:Name="Slide1" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC"> 
        <Image x:Name="Photo1" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/> 
       </Grid> 
       <Grid x:Name="Slide2" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC"> 
        <Image x:Name="Photo2" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/> 
       </Grid> 
      </StackPanel>  
     </ScrollViewer> 
    </Grid> 
+0

左または右にフリックするときにコンテンツ(つまり画像ソースのプロパティ)を変更することを検討しましたか?はるかに簡単です。 –

+0

本当はそれはほんのちょうどあきらめていて、私はそれほど遠く離れていません。 – Subcreation

答えて

1

それは私がちょうど、ユーザーが直接操作得ることからScrollViewerのを防止し、それを手動で配置する場合、私はかなりよく作品を説明し、セットアップが判明します。これは、私が言及したほとんどの不具合を引き起こしていた物理的効果を排除します。

XAML

<ScrollViewer x:Name="SlideScroller" VerticalScrollBarVisibility="Disabled" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Left" VerticalAlignment="Top"> 
      <StackPanel x:Name="SlidePanel" Orientation="Horizontal" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left"> 
      </StackPanel> 
     </ScrollViewer> 
<Rectangle x:Name="ScrollInterceptRect" Margin="0,0,0,-31" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" HorizontalAlignment="Left" VerticalAlignment="Top"> 

分離コード

public MainPage() 
    { 
     InitializeComponent(); 

     ScrollInterceptRect.MouseLeftButtonUp += new MouseButtonEventHandler(ScrollInterceptRect_MouseLeftButtonUp); 
     ScrollInterceptRect.MouseLeftButtonDown += new MouseButtonEventHandler(ScrollInterceptRect_MouseLeftButtonDown); 
     ScrollInterceptRect.MouseMove += new MouseEventHandler(ScrollInterceptRect_MouseMove); 
    } 
    //... 
    NavigationIndices navigationIndices = new NavigationIndices(); 
    readonly double swipeThreshold = 80.0; 
    SwipeDirection swipeDirection; 
    bool tapCancelled; 
    Point swipeDelta; 
    Point swipeStartPosition; 
    double startScrollOffsetX; 
    void SlideScroller_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     swipeStartPosition = e.GetPosition(this); 
     startScrollOffsetX = SlideScroller.HorizontalOffset; 
    } 
    void ScrollInterceptRect_MouseMove(object sender, MouseEventArgs e) 
    { 
     Point touchPosition = e.GetPosition(this); 
     swipeDelta = new Point() { X = swipeStartPosition.X - touchPosition.X, Y = swipeStartPosition.Y - touchPosition.Y }; 
     SlideScroller.ScrollToHorizontalOffset(startScrollOffsetX + swipeDelta.X); 
     // swipe right 
     if (swipeDelta.X > swipeThreshold) 
     { 
      swipeDirection = SwipeDirection.Left; 
      tapCancelled = true; 
     } 
     // swipe left 
     else if (swipeDelta.X < -swipeThreshold) 
     { 
      swipeDirection = SwipeDirection.Right; 
      tapCancelled = true; 
     } 
    } 
    void ScrollInterceptRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     if (swipeDirection == SwipeDirection.Left && navigationIndices.X < photos.Count - 1 && photos[navigationIndices.X] != null) 
     { 
      navigationIndices.X++; 
     } 
     // only go back when you aren't already at the beginning 
     else if (swipeDirection == SwipeDirection.Right && navigationIndices.X > 0) 
     { 
      navigationIndices.X--; 
     } 
     if (!tapCancelled) 
     { 
      // handle tap 
     } 
     else 
     { 
      animateScrollViewerToCurrentPhoto(); 
     } 
    } 

これは(私も私のアプリで何かのために垂直方向のスワイプを使用してわかりやすくするためにビットを簡素化し、私はScrollViewerのをアニメーション化していますどのように省略されている - おそらくそれの価値があるのは自分の投稿です)。

私はあなたがこれに対して提供できる改善や、それをより良い方法で実装するための提案を聞いて欲しいです。パネルクラスを拡張するか、カスタムビヘイビアとして拡張します。思考?

関連する問題