2013-02-02 37 views
1

我想創建一個簡單的相冊(Windows應用商店應用程序)使用翻轉視圖。一個簡單的相冊與捏和縮放使用FlipView

我在ScrollViewer中嵌入了Image元素。我可以瀏覽照片,但我期待着做以下事情。

  • 圖像應該統一填充屏幕的高度[當圖像沒有放大時]。我爲幾件物品準備了垂直滾動條。當所有圖像的高度相同時,我沒有這個問題。
  • 當我改變屏幕的方向時,圖像的一部分被剪切在右側。
  • 當我在頁面之間移動時,scrollviewer應該忘記縮放級別(重置縮放因子爲1)。

這是我現在的代碼。我究竟做錯了什麼?我應該在EventHandler中添加什麼來重置我的ScrollViewer的縮放因子。

<FlipView 
    Name="MainFlipView" 
    Margin="0" 
    Height="{Binding ActualHeight, ElementName=pageRoot, Mode=OneWay}" 
    Width="{Binding ActualWidth, ElementName=pageRoot, Mode=OneWay}" 
    Background="Black"> 
     <FlipView.ItemTemplate> 
       <DataTemplate> 
        <ScrollViewer Name="myScrollViewer" ZoomMode="Enabled" 
           Height="{Binding ActualHeight, ElementName=pageRoot, Mode=OneWay}" 
           Width="{Binding ActualWidth, ElementName=pageRoot, Mode=OneWay}" 
           HorizontalAlignment="Center" 
           VerticalAlignment="Center" 
           HorizontalScrollBarVisibility="Auto" 
           VerticalScrollBarVisibility="Auto" 
           MinZoomFactor="0.5" 
           MaxZoomFactor="2.5" 
           Margin="0" > 
         <Image Source="{Binding Path=Image}" 
           Name="MainImage" Stretch="Uniform" /> 
        </ScrollViewer> 
      </DataTemplate> 
     </FlipView.ItemTemplate> 
    </FlipView> 

回答

4

說什麼user2199147應該解決您的第一點,其他兩個我不得不以編程方式解決,但應當指出的是,我還不得不使用VisualTreeHelper類,你將不得不進口,以及擴展方法來幫助我使用助手類。

首先,我不得不從VisualTreeHelper擴展,它找到的第一個元件在FlipView是任何類型的方法:

private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject 
{ 
    if (parentElement != null) 
    { 
     var count = VisualTreeHelper.GetChildrenCount(parentElement); 
     if (count == 0) 
      return null; 

     for (int i = 0; i < count; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parentElement, i); 

      if (child != null && child is T) 
       return (T)child; 
      else 
      { 
       var result = FindFirstElementInVisualTree<T>(child); 
       if (result != null) 
       { 
        return result; 
       } 
      } 
     } 
    } 
    return null; 
} 

對於進入縱向模式,我添加了一個回調處理WindowSizeChanged,並簡單地在翻蓋視圖重置所有ScrollViewer背到其默認

private void WindowSizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e) 
{ 
    //Reset scroll view size 
    int count = MainFlipView.Items.Count; 
    for(int i = 0; i < count; i++) 
    { 
     var flipViewItem = MainFlipView.ItemContainerGenerator.ContainerFromIndex((i)); 
     var scrollViewItem = FindFirstElementInVisualTree<ScrollViewer>(flipViewItem); 
     if (scrollViewItem is ScrollViewer) 
     { 
      ScrollViewer scroll = (ScrollViewer)scrollViewItem; 
      scroll.Height = e.Size.Height; //Reset width and height to match the new size 
      scroll.Width = e.Size.Width; 
      scroll.ZoomToFactor(1.0f);//Zoom to default factor 
     } 
    } 
} 

然後在你的構建或者您需要Window.Current.SizeChanged += WindowSizeChanged;以便回調被調用。

現在,設置每個ScrollViewer回其默認位置,我們做了類似的過程,只是每當FlipView選擇改變,我們將重置ScrollViewer恢復爲默認縮放因子

private void FlipViewSelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (sender is FlipView) 
    { 
     FlipView item = (FlipView)sender; 
     var flipViewItem = ((FlipView)sender).ItemContainerGenerator.ContainerFromIndex(((FlipView)sender).SelectedIndex); 
     var scrollViewItem = FindFirstElementInVisualTree<ScrollViewer>(flipViewItem); 
     if (scrollViewItem is ScrollViewer) 
     { 
      ScrollViewer scroll = (ScrollViewer)scrollViewItem; 
      scroll.ScrollToHorizontalOffset(0); 
      scroll.ScrollToVerticalOffset(0); 
      scroll.ZoomToFactor(1.0f); 
     } 
    } 
} 

而且再次,我們必須在構造函數中看起來像MainFlipView.SelectionChanged += FlipViewSelectionChanged;

我知道這些方法看起來真的很迂迴和迂迴,因爲它們是,但它是什麼對我有用,我希望這可以幫助秒。

+0

謝謝你爲我工作。但即使在FlipView中,高度=「{綁定ActualHeight,ElementName = pageRoot,Mode = OneWay}」 Width =「{Binding ActualWidth,ElementName = pageRoot,Mode = OneWay}」我必須設置新的高度和寬度在WindowSizeChanged事件處理程序中。 – alrk

+0

啊,是的。我也有這個問題。我對Windows 8 API等並不熟悉,所以我所做的大部分工作都非常黑客。 – EmptyFlash

0

爲什麼你有一個ScrollViewer FlipViewItemTemplate? Thie模板將用於每個項目,因此每個圖像添加到您的ItemList。 表示它應該足以讓您的模板中的圖像元素。 這應該至少避免滾動條的圖像比你的屏幕大,導致然後Stretch =「Uniform」應該處理調整大小...

+3

? – alrk

1

嘗試更改從scrollviewer到圖像的高度和寬度綁定。

<FlipView 
    Name="MainFlipView" 
    Margin="0" 
    Height="{Binding ActualHeight, ElementName=pageRoot, Mode=OneWay}" 
    Width="{Binding ActualWidth, ElementName=pageRoot, Mode=OneWay}" 
    Background="Black"> 
     <FlipView.ItemTemplate> 
       <DataTemplate> 
        <ScrollViewer Name="myScrollViewer" ZoomMode="Enabled" 

           HorizontalAlignment="Center" 
           VerticalAlignment="Center" 
           HorizontalScrollBarVisibility="Auto" 
           VerticalScrollBarVisibility="Auto" 
           MinZoomFactor="0.5" 
           MaxZoomFactor="2.5" 
           Margin="0" > 
         <Image Source="{Binding Path=Image}" 
             Height="{Binding ActualHeight, ElementName=pageRoot, Mode=OneWay}" 
             Width="{Binding ActualWidth, ElementName=pageRoot, Mode=OneWay}" 
             Name="MainImage" Stretch="Uniform" /> 
        </ScrollViewer> 
      </DataTemplate> 
     </FlipView.ItemTemplate> 
    </FlipView> 
1

對WinRT的良好做法是:

1)請附加屬性的ScrollViewer,這將改變ZoomFactor

public class ScrollViewerExtension : DependencyObject 
{ 
    public static readonly DependencyProperty ScrollViewerZoomFactorProperty = DependencyProperty.RegisterAttached(
     "ScrollViewerZoomFactor", typeof(double), typeof(ScrollViewerExtension), new PropertyMetadata(default(double), OnZoomFactorChanged)); 

    public static void SetScrollViewerZoomFactor(DependencyObject element, double value) 
    { 
     element.SetValue(ScrollViewerZoomFactorProperty, value); 
    } 

    public static double GetScrollViewerZoomFactor(DependencyObject element) 
    { 
     return (double)element.GetValue(ScrollViewerZoomFactorProperty); 
    } 

    private static void OnZoomFactorChanged(DependencyObject depObject, DependencyPropertyChangedEventArgs args) 
    { 
     if (depObject is ScrollViewer) 
     { 
      var scrollViewer = (ScrollViewer)depObject; 
      var zoomValue = (double)args.NewValue; 
      if (!Double.IsNaN(zoomValue)) 
       scrollViewer.ZoomToFactor((float)zoomValue); 
     } 
     else 
     { 
      throw new Exception("ARE YOU KIDDING ME ? ITS NOT SCROLLVIEWER"); 
     } 
    } 
} 

2)換FlipViewItem模板

<Style TargetType="FlipViewItem"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate> 
       <Grid Width="1040"> 
        <ScrollViewer HorizontalAlignment="Stretch" 
            HorizontalScrollBarVisibility="Auto" 
            MaxZoomFactor="4" 
            MinZoomFactor="1" 
            Tag="{Binding IsSelected}" 
            VerticalScrollBarVisibility="Auto" 
            VerticalScrollMode="Auto" 
            ZoomMode="Enabled" 
            extension:ScrollViewerExtension.ScrollViewerZoomFactor="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Converter={StaticResource IsSelectedToZoom}}"> 
         <ContentPresenter /> 
        </ScrollViewer> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

3)創建轉換器,它將改變Scro如果未選擇項目,則將llViewerZoomFactor設置爲默認值。

public class IsSelectedToZoomConverter :DependencyObject, IValueConverter 
{ 

    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     var val = (bool) value; 
     return val ? Double.NaN : 1.0; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, string language) 
    { 
     throw new NotImplementedException(); 
    } 
} 

4)FlipView代碼看起來就像這樣:

<FlipView x:Name="FlipView" 
      Grid.Row="5" 
      Width="1040" 
      MinHeight="392" 
      MaxHeight="600" 
      ItemsSource="{Binding Path=CurrentSession.Photos}" 
      Visibility="{Binding CurrentSession.HasContent, 
           Converter={StaticResource BoolToVisibility}}"> 
    <FlipView.ItemContainerStyle> 
    <Style TargetType="FlipViewItem"> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate> 
      <Grid Width="1040"> 
       <ScrollViewer HorizontalAlignment="Stretch" 
          HorizontalScrollBarVisibility="Auto" 
          MaxZoomFactor="4" 
          MinZoomFactor="1" 
          Tag="{Binding IsSelected}" 
          VerticalScrollBarVisibility="Auto" 
          VerticalScrollMode="Auto" 
          ZoomMode="Enabled" 
          extension:ScrollViewerExtension.ScrollViewerZoomFactor="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                          Path=IsSelected, 
                          Converter={StaticResource IsSelectedToZoom}}"> 
        <ContentPresenter /> 
       </ScrollViewer> 
      </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
     </Setter> 
    </Style> 

    </FlipView.ItemContainerStyle> 
    <FlipView.ItemTemplate> 
     <DataTemplate> 
     <Image HorizontalAlignment="Stretch" Source="{Binding Path=Path}" /> 
     </DataTemplate> 
    </FlipView.ItemTemplate> 
</FlipView> 
在這種情況下如何處理變焦