文章だと分かりにくいと思いますが
ストアアプリでウィンドウ幅が上記のように変化しても全体が見えている状態で縦横比が維持される表示方法(俗にいうサイドパネルやレターボックスというもの)はよく目にします
こんな表示を行いつつ、FlipView でページめくりもできてピンチで拡縮もできるようにする場合・・・これが意外と難しい;
一応それっぽい表示になったのが次のコード
<FlipView x:Name="flipView" ItemsSource="{Binding Items}"> <FlipView.ItemTemplate> <DataTemplate> <ctrl:UnfiormImageView /> </DataTemplate> </FlipView.ItemTemplate> </FlipView>
FlipView の中の ItemTemplate に UserControl を埋め込んで・・・
<UserControl x:Class="WindowsStoreApp.Controls.UnfiormImageView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:WindowsStoreApp1.Controls" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <ScrollViewer x:Name="scrollViewer" HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Auto" VerticalScrollBarVisibility="Auto" VerticalScrollMode="Auto" ZoomMode="Enabled"> <Image x:Name="image" HorizontalAlignment="Center" VerticalAlignment="Center" Source="ms-appx:///Assets/photo.jpg" /> </ScrollViewer> </UserControl>
ZoomMode="Enabled" にした ScrollViewer の中に Image を入れて
/// <summary> /// ウィンドウサイズに合わせて Uniform を維持する画像ビューア /// </summary> public sealed partial class UnfiormImageView : UserControl { /// <summary> /// コンストラクタ /// </summary> public UnfiormImageView() { this.InitializeComponent(); Window.Current.SizeChanged += this.OnWindowSizeChanged; this.SizeChanged += this.OnSizeChanged; } /// <summary> /// 描画完了イベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="e">イベント引数</param> private void OnSizeChanged(object sender, SizeChangedEventArgs e) { this.SizeChanged -= OnSizeChanged; this.image.ImageOpened += this.OnImageOpened; } /// <summary> /// 元の画像サイズ /// </summary> private Size originalSize = new Size(); /// <summary> /// 画像表示完了イベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="e">イベント引数</param> private void OnImageOpened(object sender, RoutedEventArgs e) { this.image.ImageOpened -= this.OnImageOpened; this.originalSize.Width = this.image.ActualWidth; this.originalSize.Height = this.image.ActualHeight; this.UpdateSize(); } /// <summary> /// ウィンドウサイズ変更イベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="e">イベント引数</param> private void OnWindowSizeChanged(object sender, WindowSizeChangedEventArgs e) { this.UpdateSize(); } /// <summary> /// サイズの更新 /// </summary> private void UpdateSize() { if (this.image.ActualWidth < this.image.ActualHeight) { var height = Window.Current.Bounds.Height - 17; this.image.Width = Math.Floor(this.originalSize.Width * height / this.originalSize.Height); this.image.Height = height; } else { var width = Window.Current.Bounds.Width - 17; this.image.Height = Math.Floor(this.originalSize.Height * width / this.originalSize.Width); this.image.Width = width; } } /// <summary> /// 子要素の破棄 /// </summary> protected override void OnDisconnectVisualChildren() { Window.Current.SizeChanged -= OnWindowSizeChanged; this.image.ImageOpened -= this.OnImageOpened; this.SizeChanged -= OnSizeChanged; base.OnDisconnectVisualChildren(); } }
ウィンドウサイズ変更時に無理やり Image のサイズを調整するとそれっぽい動作になりました
17 px 減算しているのはスクロールバーの幅の分だけ小さくしないとスクロールバーが表示されるためです