かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

UWPでファイルのドロップをしたい

以下のような感じでいけます。

まず、ドロップのターゲットにAllowDropプロパティをTrueにします。そしてDropOverイベントでドロップされたときの見た目を調整したりします。そして、Dropイベントで、イベント引数のDataViewプロパティのContainsメソッドでドロップされたコンテンツを確認して処理をします。

例えば画面の左半分にドロップされたファイルの名前のリストを、画面の右半分に置いたListViewに表示する場合は以下のようなコードになります。

<Page x:Class="App35.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App35"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid Background="DarkGray"
              AllowDrop="True"
              DragOver="Grid_DragOver"
              Drop="Grid_Drop">
        </Grid>
        <ListView x:Name="ListView"
                  Grid.Column="1" />
    </Grid>
</Page>

コードビハインドは以下のようになります。

using System;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

// 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください

namespace App35
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void Grid_DragOver(object sender, DragEventArgs e)
        {
            // コピーのアイコンに切り替える
            e.AcceptedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
        }

        private async void Grid_Drop(object sender, DragEventArgs e)
        {
            // ファイルの場合
            if (e.DataView.Contains(StandardDataFormats.StorageItems))
            {
                // ファイルのパスをListViewに表示する
                var items = await e.DataView.GetStorageItemsAsync();
                this.ListView.ItemsSource = items.Select(x => x.Path).ToArray();
            }
        }
    }
}

実行するとこんな感じになります。

f:id:okazuki:20160221162616p:plain

ドロップすると

f:id:okazuki:20160221162659p:plain

リストに表示されます。

f:id:okazuki:20160221162752p:plain