SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

UWPアプリ開発の最前線

UWPアプリでファイルマネージャーを作ろう!
~ついにWindows 10 1803で実現

UWPアプリ開発の最前線 第8回

フォルダー/ファイルが選択されたらその情報を表示する

 最後に、ノードをクリックするなどして選んだときに、その情報を画面の右側に表示するようにしてみましょう。

表示用のデータクラスを用意する

 ノードが選択されたとき、データ表示用の複数のコントロールにコードビハインドからそれぞれの値をセットするという方法でも作れますが、ここでは表示用のデータクラスを用意しておいてそのオブジェクトをUIにバインドするようにしましょう。

 表示に使うデータクラスは、次のコードのようなプロパティを持ったものです。

表示に使うデータクラス(StorageItemInfo.cs
public class StorageItemInfo
{
  public string Name { get; private set; } // フォルダー名/ファイル名
  public string Path { get; private set; } // フォルダー/ファイルまでのパス
  public DateTimeOffset DateCreated { get; private set; } // 作成日時
  public FileAttributes Attributes { get; private set; } // 属性
  public string DisplayType { get; private set; } // 種類
  public ulong Size { get; private set; } // サイズ
  public Windows.UI.Xaml.Media.ImageSource Thumbnail { get; private set; } // サムネイル

  // プロパティを表示用にフォーマットした文字列
  public string DateCreatedString => DateCreated.ToString("yyyy/MM/dd HH:mm:ss");
  public string SizeString => Size.ToString("#,##0");
}

表示用のデータクラスのインスタンスを作る

 IStorageItemオブジェクトを受け取ってデータクラスのインスタンスを作るメソッドを、データクラス内に用意しておきましょう(次のコード)。サムネイルを取得してビットマップに変換するのが、ちょっと面倒です。

表示用のデータクラスのインスタンスを作る静的メソッド(StorageItemInfo.cs
public static async Task<StorageItemInfo> Create(IStorageItem item)
{
  var itemProperties = item as IStorageItemProperties;

  // サムネイルをビットマップとして取得する(ローカル関数)
  async Task<Windows.UI.Xaml.Media.Imaging.BitmapImage>
    GetThumbnailBitmapAsync()
  {
    var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
    StorageItemThumbnail thumbnail
      = await itemProperties?.GetThumbnailAsync(ThumbnailMode.SingleItem, 256);
    if (thumbnail != null)
      bitmapImage.SetSource(thumbnail);
    return bitmapImage;
  }

  // StorageItemInfoオブジェクトを作る
  var itemInfo = new StorageItemInfo()
  {
    Name = item.Name,
    Path = System.IO.Path.GetDirectoryName(item.Path),
    DateCreated = item.DateCreated,
    Attributes = item.Attributes,
    DisplayType = itemProperties?.DisplayType,
    Thumbnail = await GetThumbnailBitmapAsync(),
  };

  // ファイルの場合、ファイルサイズもStorageItemInfoに追加する
  if (item is StorageFile file)
  {
    var basicProperties = await file.GetBasicPropertiesAsync();
    itemInfo.Size = basicProperties.Size;
  }

  return itemInfo;
}

MainPageクラスに表示用のデータを持たせる

 上記の表示用データのインスタンスを、MainPageクラスに持たせられるようにしておきます(次のコード)。後ほど、イベントハンドラーから実体をセットします。

表示用データのインスタンスを保持する場所を用意する(MainPage.xaml.cs
public sealed partial class MainPage : Page
{
  // フォルダー/ファイルの情報を表示するためのデータ
  private StorageItemInfo ItemInfo { get; set; }

情報表示用のUIを作る

 画面を適当に左右に分割して、ここまで作ってきたTreeViewコントロールは左側に入れ、右側には次のコードのようなUIを追加します。テキストブロックなどには、上記の表示用データのインスタンスをバインドしています。

情報を表示するためのUIを追加した(MainPage.xaml
<Grid Grid.Column="2" VerticalAlignment="Center" Margin="10">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
  </Grid.RowDefinitions>
  <Grid>
    <Image Source="{x:Bind ItemInfo.Thumbnail}" MinWidth="256" MinHeight="192"/>
  </Grid>
  <StackPanel Grid.Row="1">
    <TextBlock Text="{x:Bind ItemInfo.Name}" TextWrapping="Wrap" />
    <TextBlock Text="{x:Bind ItemInfo.Path}" TextWrapping="Wrap" />
    <TextBlock Text="{x:Bind ItemInfo.DisplayType}" />
    <TextBlock Text="{x:Bind ItemInfo.Attributes}" />
    <TextBlock Text="{x:Bind ItemInfo.DateCreatedString}" />
    <TextBlock Text="{x:Bind ItemInfo.SizeString}" />
  </StackPanel>
</Grid>

 コードの全体はMainPage.xamlをご覧ください。このサンプルコードでは、左右分割の配分を変更できるように、Windows Community Toolkit ControlsGridSplitterも使っています。

イベントハンドラーで情報を表示する

 イベントは、TreeViewコントロールのItemInvokedイベントを使います。まず、XAML側でイベントハンドラーを追加します(次のコード)。

ノードが選択されたときのイベントハンドラーを追加する(MainPage.xaml
<TreeView x:Name="TreeView1" SelectionMode="Single"
          Expanding="TreeView1_Expanding"
          ItemInvoked="TreeView1_ItemInvoked"
          />

 次に、イベントハンドラーを実装します(次のコード)。引数にはノードが渡ってきます。そのContentプロパティにはIStorageItemオブジェクトが納められています(そのように作ってきました)。IStorageItemオブジェクトから表示用のStorageItemInfoを作り、ページのプロパティにセットします。最後にページのBindings.Updateメソッドを呼び出すと、新しいデータが画面に反映されます。Bindings.Update();と書いたときにエラーが出るかもしれませんが、ビルドすれば解消されます。

ノードが選択されたときのイベントハンドラーを実装する(MainPage.xaml.cs
private async void TreeView1_ItemInvoked(TreeView sender, TreeViewItemInvokedEventArgs args)
{
  if (args.InvokedItem is TreeViewNode node)
  {
    this.ItemInfo = await StorageItemInfo.Create(node.Content as IStorageItem);
    this.Bindings.Update();
  }
}

 これで完成です。実行してみると、次の画像のようになります。

フォルダーの情報が表示されている
フォルダーを選択したところ
ファイルの情報が表示されている
ファイルを選択したところ

 実用的なファイルマネージャーにするには、選択したフォルダー/ファイルに対する操作(移動/コピー/削除、ファイルのオープンなど)や、F5キーなどでのリフレッシュ動作、あるいは検索やドラッグ&ドロップへの対応など、まだまだ実装したいことはたくさんありますが、今回の記事ではここまでにしたいと思います。

次のページ
まとめ

関連リンク

この記事は参考になりましたか?

UWPアプリ開発の最前線連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/11072 2018/09/27 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー