質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

2057閲覧

UWPのFlipViewに多数(200枚とか)のファイルを登録してストレスなくめくる方法

SouthAzabu

総合スコア11

UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2019/07/08 06:50

前提・実現したいこと

FlipViewの勘所を教えてください。

発生している問題・エラーメッセージ

(1)いちどに200枚とかを登録するととても遅い
(2)メモリが不足して落ちる。

該当のソースコード

xaml

1<Page 2 x:Class="App1.MainPage" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="using:App1" 6 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 7 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 8 mc:Ignorable="d" 9 Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Loaded="Page_Loaded"> 10 11 <Grid> 12 <FlipView x:Name="MainFlip" /> 13 </Grid> 14</Page> 15

C#

1using System; 2using System.IO; 3using Windows.UI.Xaml; 4using Windows.UI.Xaml.Controls; 5using Windows.UI.Xaml.Media.Imaging; 6 7namespace App1 8{ 9 public sealed partial class MainPage : Page 10 { 11 public MainPage() 12 { 13 this.InitializeComponent(); 14 } 15 16 private void Page_Loaded(object sender, RoutedEventArgs e) 17 { 18 var files = Directory.EnumerateFiles(@".\", "*.jpg"); 19 foreach (var file in files) 20 { 21 var bitmap = new BitmapImage(new Uri(file)); 22 Image image = new Image(); 23 image.Source = bitmap; 24 MainFlip.Items.Add(image); 25 } 26 } 27 } 28} 29

疑問点

MSDNを見たところ、そもそもFlipViewは15枚くらいを想定したコントロールらしいです。
とすると200枚とかを手軽に(たとえばフリップで)めくって表示するには、使えないものでしょうか?

(1)最初に10個くらい登録する。
(2)フリップでめくっていって、10枚めになったら、現在のを消して次の10枚を読む。
みたいなことをすれば、できなくはないのかなと思いました。

たとえばこんなコードです。

C#

1 List<string> Files; 2 int Counter = 0; 3 private void FirstStep() 4 { 5 Files.AddRange(Directory.GetFiles(@".\", "*.jpg")); 6 foreach (var file in Files) 7 { 8 var bitmap = new BitmapImage(new Uri(file)); 9 Image image = new Image(); 10 image.Source = bitmap; 11 MainFlip.Items.Add(image); 12 Counter++; 13 if (10 < Counter) break; 14 } 15 } 16 17 private void MainFlip_SelectionChanged(object sender, SelectionChangedEventArgs e) 18 { 19 if (9 < MainFlip.SelectedIndex) 20 { 21 for (int i = 0; i < 10; i++) 22 { 23 MainFlip.Items.RemoveAt(i); 24 } 25 for (int i = Counter; i < 10; i++) 26 { 27 var bitmap = new BitmapImage(new Uri(Files[i])); 28 Image image = new Image(); 29 image.Source = bitmap; 30 MainFlip.Items.Add(image); 31 Counter++; 32 if (10 < i) break; 33 } 34 } 35 } 36

でもこれは、まさかね、と思うようなひどいコードだと思いますし、もうちょっとよい方法がありそうな気がします。
FlipViewに多数のファイルを登録してストレスなくめくる方法、ご教示いただけないでしょうか。
ヒントでもよいです。

ひょっとして、FlipViewを使わず、ImageにManipulationDeltaとManipulationCompletedを実装するとかでしょうか?

XAML

1 <Image ManipulationDelta="Image_ManipulationDelta" ManipulationCompleted="Image_ManipulationCompleted"/> 2

よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Microsoft Visual Studio Community 2019
Version 16.1.3
VisualStudio.16.Release/16.1.3+29009.5
Microsoft .NET Framework
Version 4.7.03190
インストールされているバージョン:Community
Target Framework .NET Framework 4.7.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

メモリ不足になるのは表示対象となるBitmapをあらかじめ読み込んでしまうことが原因だと思います。

理想としては、必要になったら必要な分だけ画像が読み込まれて、表示されなくなったら画像がアンロードされることです。それはXamlが本来想定した使用用途ですので、Xamlとして自然な形で記述するだけで対応可能です。

その一番の近道はFlipView.ItemTemplateを通じて表示する方法を利用するといいでしょう。

https://docs.microsoft.com/ja-jp/windows/uwp/design/controls-and-patterns/flipview#specify-the-look-of-the-items

FlipView.ItemTemplateを通じて表示方法を定義することで、リストアイテム(この場合は各画像)はFlipViewによる効率的な表示が期待できるようになります。

以下は部分的なコードの例です。

xml:MainPage.xaml

1 2<FlipView x:Name="MainFlip"> 3 <FlipView.ItemTemplate> 4 <DataTemplate> 5 <Image Source="{Binding}" /> 6 </DataTemplate> 7 </FlipView.ItemTemplate> 8</FlipView>

MainPage.xaml.cs

1 2public List<Uri> ImageUrls { get; } = new List<Uri>(); 3 4private void Page_Loaded(object sender, RoutedEventArgs e) 5{ 6 var files = Directory.EnumerateFiles(@".\", "*.jpg"); 7 foreach (var file in files) 8 { 9 ImageUrls.Add(new Uri(file.FullName)); 10 } 11 12 MainFlip.ItemsSource = ImageUrls; 13} 14

こう書くとFlipView内部のパネルとして実装されているVirtualizingStackPanelによって仮想化が有効になるため、効率的に表示されることが期待できます。


あと、Directory.EnumerateFilesはUWPでは非推奨なAPIです。替わりにGetFileFromApplicationUriAsync などのStorageFile/StorageFolderを通じたアクセスを検討してみてください。

投稿2019/07/09 05:06

tor4kichi

総合スコア763

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SouthAzabu

2019/07/09 06:14

昨日、いけてないコードで動作することを確認しました。 でも、XamlのDataTemplateよさそうです。試してみます。ありがとうございます。
SouthAzabu

2019/07/10 00:18

検証しました。動作することを確認しました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問