WPFでReactiveCommandを使ってドラッグアンドドロップ

C# コンピュータ
C#

ドラッグアンドドロップのサンプルです。

プロジェクトの作成

ソースコード

ファイル名:MainWindow.xaml

<Window x:Class="WpfProgram2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:i="clr-namespace:Microsoft.Xaml.Behaviors;assembly=Microsoft.Xaml.Behaviors"
        xmlns:interactivity="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
        xmlns:local="clr-namespace:WpfProgram2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Closed">
            <interactivity:EventToReactiveCommand Command="{Binding WindowClosedCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <StackPanel
            Background="Black"
            AllowDrop="True">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="DragEnter">
                    <interactivity:EventToReactiveCommand Command="{Binding DragEnterCommand}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="Drop">
                    <interactivity:EventToReactiveCommand Command="{Binding DropCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </StackPanel>
    </Grid>
</Window>

ファイル名:MainWindowViewModel.cs

using System;
using System.ComponentModel;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System.Reactive.Disposables;

using System.Diagnostics;
using System.Windows;
using System.Linq;

namespace WpfProgram2;

public class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    protected virtual void OnPropertyChanged(string name)
    {
        if (PropertyChanged == null) return;
        PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    private CompositeDisposable Disposable { get; } = new ();
    public ReactiveCommand<EventArgs> WindowClosedCommand { get; }
    public ReactiveCommand<DragEventArgs> DragEnterCommand { get; }
    public ReactiveCommand<DragEventArgs> DropCommand { get; }
    public MainWindowViewModel()
    {
        WindowClosedCommand = new ReactiveCommand<EventArgs>()
            .WithSubscribe(e => Disposable.Dispose());
        
        DragEnterCommand = new ReactiveCommand<DragEventArgs>()
            .WithSubscribe(e =>
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    e.Effects = DragDropEffects.Copy;
                    e.Handled = true;
                    return;
                }
                e.Effects = DragDropEffects.None;
                e.Handled = false;
            });
        
        DropCommand = new ReactiveCommand<DragEventArgs>()
            .WithSubscribe(e =>
            {
                var files = e.Data.GetData(DataFormats.FileDrop) as string[];
                if (files is null || !files.Any()) return;
                MessageBox.Show($"{files[0]}");
            });
    }
}

動作内容

実行すると背景が黒のウィンドウが表示されます。

そちらにエクスプローラーなどからファイルをドラッグアンドドロップします。

ドラッグアンドドロップしたファイル名がメッセージボックスに表示されたら成功です。

コメント