UWPでファイルのドロップして画像表示させる

UWPでファイルのドロップをしたい – かずきのBlog@hatena
http://blog.okazuki.jp/entry/2016/02/21/162757

を見て、ああ「AllowDropプロパティをTrue」にするだけでよかったんだ、と思って画像の表示まで試してみました。

private void Grid_DragOver(object sender, DragEventArgs e)
{
    e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Link;
}

private async void Grid_Drop(object sender, DragEventArgs e)
{
    // ファイルの場合
    if (e.DataView.Contains(StandardDataFormats.StorageItems))
    {
        var items = await e.DataView.GetStorageItemsAsync();
        if ( items.Count > 0 )
        {
            // 画像ファイルを表示する
            var it = items[0];
            var sf = it as Windows.Storage.StorageFile;
            var fs = await sf.OpenReadAsync();
            var bi = new BitmapImage();
            bi.SetSource(fs);
            this.image1.Source = bi;
        }
    }
}

private async void button_Click(object sender, RoutedEventArgs e)
{
    //Storageファイルを取得
    var picker = new FileOpenPicker();
    picker.FileTypeFilter.Add(".png");
    var file = await picker.PickSingleFileAsync();
    var fs = await file.OpenReadAsync();
    var bi = new BitmapImage();
    bi.SetSource(fs);
    this.image1.Source = bi;
}

コツは、ドラッグしたファイルが IStorageItem なので StorageFile にキャストしてしまえば ok です。これでストアアプリの Storage として扱えるので定番処理で BitmapImage に突っ込みます。
と、さっくりと書いているように見えますが、最初は it.Path のようにパスを取ってきてメモリ上に変換してとあれこれやっていたんですよね。結構苦労しましたが、StorageFile にキャストができることが分かって、すっきりした状態になります。
ちなみに、ボタンのほうは試しに FileOpenPicker で開いたものです。

こんな風に UWP アプリにドロップできます。

ピクチャフォルダ以外もアクセスできる

8.1 のストアアプリの場合、パッケージマニフェストで「ピクチャライブラリ」を選択しないと、Windows.Storage.KnownFolders.PicturesLibrary がアクセスできなかったのですが、この方法だとどんなフォルダにもアクセスできます。UWP から PicturesLibrary を参照するときにアクセス制限がかかるんですが、これって意図した動きですよね? 8.1 のときがどうだったか覚えていないのですが、PicturesLibrary を使わない限り、ローカル PC のどのフォルダもアクセスできます。

おそらく、

– ピッカーやドラッグの場合は、ユーザーが「意図」して操作したので、どこでもアクセスできる。
– プログラムが自動で PicturesLibrary 配下を探ろうとするとアクセス制限がかかる。

という思想なのかもしれません。

カテゴリー: 開発 パーマリンク