Search code examples
c#wpfwinformsdrag-and-dropwindowsformshost

WPF with WindowsFormsHost Drag and Drop


I'm struggling to get Drag and Drop work on WindowsFormsHost when I drag on a file from the desktop, the Drop event just doesn't fire.

I created a sample project to demonstrate:

You need to reference WindowsFormsIntegration and System.Windows.Forms

MainWindow.xaml

<Window x:Class="WpfApp3.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:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        mc:Ignorable="d"
        AllowDrop="true"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <WindowsFormsHost 
                Background="red" 
                Height="200"
                AllowDrop="true"
                Drop="WindowsFormsHost_Drop">
                <wf:MaskedTextBox Height="200"  x:Name="mtbDate" Mask="00/00/0000"/>
            </WindowsFormsHost>
            <ListBox Name="LogList" />
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;

namespace WpfApp3
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            LogList.Items.Add("initialized");
        }


        private void WindowsFormsHost_Drop(object sender, DragEventArgs e)
        {
            LogList.Items.Add("fileDropped");
            LogList.Items.Add($"FileSource: {e.Source}");
        }
    }
}

Can anyone tell me what I'm missing?


Solution

  • Well I tested this qiute a bit and I can only guess that this is due to incompability of WinForms and WPF. From what I researched, events not always flow thorugh controls when those technologies are invloved.

    But I can suggest something to work around this limitation - keep events in WPF controls, so define invisible, underlying control (that will occupy exactly the same area as WindowsFormsHost) to capture events:

    <Grid>
        <Border
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch"
            AllowDrop="True"
            Background="Transparent"
            Drop="WindowsFormsHost_Drop" />
        <WindowsFormsHost
            Name="wfh"
            Height="200"
            Background="red">
            <wf:MaskedTextBox
                x:Name="mtbDate"
                Height="200"
                Mask="00/00/0000" />
        </WindowsFormsHost>
    </Grid>
    

    I think that you might try even to set IsHitTestVisible of WindowsFormsHost to false, so all UI events should fall through - but it is up to you to test and decide if you want it.