1

Flip Viewを使って簡単なフォトアルバム(Windowsストアアプリ)を作ろうとしています。

ScrollViewer 内に Image 要素が埋め込まれています。写真を閲覧することはできますが、次のことを行うことを検討しています。

  • [画像がズームされていない場合]、画像は画面の高さを均一に満たす必要があります。いくつかの項目で垂直スクロールバーが表示されます。すべての画像の高さが同じ場合、この問題は発生しません。
  • 画面の向きを変えると、画像の一部が右側で切り取られます。
  • ページ間を移動すると、スクロールビューアはズームレベルを忘れる(ズーム係数を1にリセットする)必要があります。

これは私が今持っているコードです。私は何を間違っていますか?ScrollViewer のズーム倍率をリセットするには、EventHandler に何を追加すればよいでしょうか。

<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

4 に答える 4

4

user2199147が言ったことは、あなたの最初の箇条書きを解決するはずです.他の2つはプログラムで修正する必要がありまし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;

これらの方法は本当にハックで回りくどいように見えますが、それは私にとってはうまくいったので、これが役立つことを願っています.

于 2013-06-07T03:57:55.047 に答える
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>
于 2013-03-22T12:15:47.153 に答える
0

FlipViewItemTemplate 内に ScrollViewer があるのはなぜですか? このテンプレートはアイテムごとに使用されるため、画像ごとに ItemList に追加します。テンプレート内に Image 要素があれば十分です。これにより、少なくとも画面よりも大きい画像のスクロールバーを回避する必要があります。その場合、 Stretch="Uniform" がサイズ変更を処理する必要があります...

于 2013-03-20T15:28:00.940 に答える