2011-07-16 14 views
10

Występują różne problemy, tworząc efekt bardzo podobny do paska zdjęć w aplikacji Aparat.Jak zaimplementować pasek fotografii w stylu aplikacji na WP7?

Wszystko, co chcę zrobić, to wyświetlić rząd siatek, z których każdy ma te same wymiary co ekran (w pionie lub poziomie). Już musiałem zrobić coś hackowanego i create dependency properties that the grids width and height properties bind to, aby zachować proporcje.

To działa dobrze. Ale kiedy tworzę StackPanel dla mojego paska i implementuję nawigację (lub po prostu powiększam z transformacją z-index) widzę, że mój StackPanel nie może wyświetlać większych rozmiarów niż wymiary ekranu (jest przycięty do rozmiaru tylko jednej siatki) . Pomyślałem, że znalazłem wpis opisujący ten problem, ale nie mogę go teraz znaleźć - proszę napisać, jeśli wiesz, o którym postem myślę lub czy wiesz więcej o tym ograniczeniu.

Jedyne obejście, jakie znalazłem, to użycie ScrollViewera, który absolutnie nie jest pożądanym zachowaniem, ale pozwala, aby StackPanel był szerszy niż ekran.

Moim prawdziwym problemem jest zachowanie ScrollViewer - ponieważ muszę przeskakiwać z siatki na siatkę (tak jak robi to zdjęcie) zamiast swobodnie przewijać, i o ile mogę powiedzieć, że HorizontalOffset nie jest właściwością animacyjną. Mogę zmusić go do animowania, wywołując ScrollToHorizontalOffset co 15 milisekund, zasadniczo wdrażając mój własny efekt łagodzenia ręcznie. To wydaje się być ogromnym hackerem, a zachowanie jest bardzo niestabilne (albo nie dostaję zdarzenia ManipulationCompleted za każdym razem, kiedy się tego spodziewam - na końcu każdej operacji machnięcia - albo wbudowana fizyka bezwładności ScrollViewera zakłóca mój efekt).

Czy ktoś wie lepiej obejść problemy, na które się natknąłem, lub zupełnie inny sposób uzyskania paska Photo Camera w Silverlight?

Rozważałem użycie kontrolki Pivot, ale nie jest to dokładnie to, czego chcę (gdybym chciał, aby każdy element był całkowicie animowany, zanim pojawi się następny, zamiast pojawiania się wszystkich dołączonych do jednego paska, powinny być mniej ograniczające sposoby, aby to osiągnąć). Co ważniejsze, pasek jest tylko jednym z wielu efektów, które chcę robić dynamicznie. Chciałbym na przemian obrócić stronę w stylu CoolIris w stylu 3D-tilt lub w stylu FlipPad. Wierzę, że gdybym mógł sprawić, by moja obecna konfiguracja działała ładnie, łatwo byłoby zaimplementować te inne efekty (jako modyfikowalne przejścia). Popełnienie kontroli jak Pivot nie zbliży mnie do tej wizji.

Tu jest mój 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

Czy zastanawiałeś się nad zmianą zawartości (np. Właściwości źródła obrazu), gdy poruszasz się w lewo lub w prawo? To znacznie prostsze. –

+0

Niezupełnie - to po prostu rezygnacja i naprawdę nie jestem tak daleko. – Subcreation

Odpowiedz

1

Okazuje się instalację opisałem działa całkiem dobrze, jeśli tylko zapobiec ScrollViewer z coraz manipulować bezpośrednio przez użytkownika i położenia go ręcznie. Eliminuje to efekty fizyki, które powodowały większość omamów, o których wspomniałem.

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

kodzie

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(); 
     } 
    } 

To jest trochę uproszczona dla jasności (ja też użyć pionowego bezstykowa czegoś w mojej aplikacji i I pominięte, jak ja animowanie ScrollViewer - prawdopodobnie godny tego postu).

Chciałbym usłyszeć wszelkie ulepszenia, które można w tym celu zaoferować, lub sugestie dotyczące lepszych sposobów wdrożenia go w ogóle. Być może rozszerzenie klasy paneli lub niestandardowe zachowanie. Myśli?

Powiązane problemy