ストアアプリで大きな画像を表示する場合、
本来こんな感じに表示される画像が
こんな風に見切れて表示されてしまうことがあります
原因はわかりませんが、140%、180% の自動スケーリングで利用される画像の横幅や縦幅が 2046px 以上の場合、正しくスケーリングされず見切れてしまうようです
仕方がないので現象回避コード
<UserControl x:Class="WindowsStoreApp9.Controls.SaclingImage" 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:WindowsStoreApp9.Controls" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="ContentRoot" mc:Ignorable="d"> <Image x:Name="innerImage" Width="{Binding Path=Width, ElementName=ContentRoot}" Height="{Binding Path=Height, ElementName=ContentRoot}" HorizontalAlignment="{Binding Path=HorizontalAlignment, ElementName=ContentRoot}" VerticalAlignment="{Binding Path=VerticalAlignment, ElementName=ContentRoot}" Stretch="{Binding Path=Stretch, ElementName=ContentRoot}" /> </UserControl>
Image コントロールを内包するユーザコントロールを作成して
/// <summary> /// 手動でスケーリングする画像コントロール /// </summary> public sealed partial class SaclingImage : UserControl { #region Source 依存関係プロパティ /// <summary> /// Source 依存関係プロパティ /// </summary> public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(string), typeof(SaclingImage), new PropertyMetadata(null, (s, e) => { var control = s as SaclingImage; if (control != null) { control.OnSourceChanged(); } })); /// <summary> /// Source 変更イベントハンドラ /// </summary> private void OnSourceChanged() { this.UpdateImage(); } /// <summary> /// Source /// </summary> public string Source { get { return (string)this.GetValue(SourceProperty); } set { this.SetValue(SourceProperty, value); } } #endregion //Source 依存関係プロパティ /// <summary> /// コンストラクタ /// </summary> public SaclingImage() { this.Stretch = Stretch.Uniform; this.InitializeComponent(); Window.Current.SizeChanged += this.OnSizeChanged; } /// <summary> /// Stretch /// </summary> public Stretch Stretch { get; set; } /// <summary> /// サイズ変更イベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="e">イベント引数</param> private void OnSizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e) { this.UpdateImage(); } /// <summary> /// 子要素破棄時の処理 /// </summary> protected override void OnDisconnectVisualChildren() { Window.Current.SizeChanged -= this.OnSizeChanged; base.OnDisconnectVisualChildren(); } /// <summary> ///画像ソースを切り替える /// </summary> private void UpdateImage() { var fileName = Path.GetFileName(this.Source); var path = this.Source.Replace(fileName, string.Empty); var extension = Path.GetExtension(fileName); var scaleMode = ResolutionScale.Invalid; try { // デザインモード用 scaleMode = DisplayInformation.GetForCurrentView().ResolutionScale; } catch (Exception) { } switch (scaleMode) { // 100% 表示 case ResolutionScale.Scale100Percent: case ResolutionScale.Scale120Percent: this.innerImage.Source = new BitmapImage( new Uri(string.Format("{0}{1}.scale-100{2}", path, fileName.Replace(extension, string.Empty), extension), UriKind.RelativeOrAbsolute)); break; // 140% 表示 case ResolutionScale.Scale140Percent: case ResolutionScale.Scale150Percent: case ResolutionScale.Scale160Percent: this.innerImage.Source = new BitmapImage( new Uri(string.Format("{0}{1}.scale-140{2}", path, fileName.Replace(extension, string.Empty), extension), UriKind.RelativeOrAbsolute)); break; // 180% 表示 case ResolutionScale.Scale180Percent: case ResolutionScale.Scale225Percent: case ResolutionScale.Invalid: this.innerImage.Source = new BitmapImage( new Uri(string.Format("{0}{1}.scale-180{2}", path, fileName.Replace(extension, string.Empty), extension), UriKind.RelativeOrAbsolute)); break; } } }
自前でスケーリングによる画像切り替えを行います これで正しくスケーリングがされました
ちなみにこの場合アプリパッケージ作成時にアプリバンドルを「表示しない」にしないと 140%、180% の画像が分割パッケージされるため、参照できなくて思い通りの動作にならないのでご注意ください