フォルダー/ファイルが選択されたらその情報を表示する
最後に、ノードをクリックするなどして選んだときに、その情報を画面の右側に表示するようにしてみましょう。
表示用のデータクラスを用意する
ノードが選択されたとき、データ表示用の複数のコントロールにコードビハインドからそれぞれの値をセットするという方法でも作れますが、ここでは表示用のデータクラスを用意しておいてそのオブジェクトをUIにバインドするようにしましょう。
表示に使うデータクラスは、次のコードのようなプロパティを持ったものです。
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オブジェクトを受け取ってデータクラスのインスタンスを作るメソッドを、データクラス内に用意しておきましょう(次のコード)。サムネイルを取得してビットマップに変換するのが、ちょっと面倒です。
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クラスに持たせられるようにしておきます(次のコード)。後ほど、イベントハンドラーから実体をセットします。
public sealed partial class MainPage : Page
{
// フォルダー/ファイルの情報を表示するためのデータ
private StorageItemInfo ItemInfo { get; set; }
情報表示用のUIを作る
画面を適当に左右に分割して、ここまで作ってきたTreeViewコントロールは左側に入れ、右側には次のコードのようなUIを追加します。テキストブロックなどには、上記の表示用データのインスタンスをバインドしています。
<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 ControlsのGridSplitterも使っています。
イベントハンドラーで情報を表示する
イベントは、TreeViewコントロールのItemInvokedイベントを使います。まず、XAML側でイベントハンドラーを追加します(次のコード)。
<TreeView x:Name="TreeView1" SelectionMode="Single"
Expanding="TreeView1_Expanding"
ItemInvoked="TreeView1_ItemInvoked"
/>
次に、イベントハンドラーを実装します(次のコード)。引数にはノードが渡ってきます。そのContentプロパティにはIStorageItemオブジェクトが納められています(そのように作ってきました)。IStorageItemオブジェクトから表示用のStorageItemInfoを作り、ページのプロパティにセットします。最後にページのBindings.Updateメソッドを呼び出すと、新しいデータが画面に反映されます。Bindings.Update();と書いたときにエラーが出るかもしれませんが、ビルドすれば解消されます。
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キーなどでのリフレッシュ動作、あるいは検索やドラッグ&ドロップへの対応など、まだまだ実装したいことはたくさんありますが、今回の記事ではここまでにしたいと思います。
