Search code examples
wpfwinformswindowsformshost

Close the WPF dialog when one clicks on a button inside the WindowsFormHost


I have a WPF dialog, that hosts a windowsFormHost control, with something like this

<Window x:Class="WPFSort.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:local="clr-namespace:WPFSort"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <WindowsFormsHost HorizontalAlignment="Left" Height="Auto"
                          Margin="87,43,0,0" VerticalAlignment="Top" Width="Auto">
            <local:SimpleWinControl />
        </WindowsFormsHost>

    </Grid>
</Window>

And for the SimpleWinControl , it is a WinForm control. When button 1 is clicked, I want

  1. The WPF dialog to be closed
  2. And the data importantdata to be "pass out" to the WPF form that calls the WPF dialog?

    public partial class SimpleWinControl : UserControl
    {
        public SimpleWinControl()
        {
            InitializeComponent();
        }
    
        public object importantdata;
    
        private void button1_Click(object sender, EventArgs e)
        {
          //how should I write the close and pass the importantdata out
    
        }
    }
    

Solution

  • You could for example add a property to your WinForms control that exposes the Button control:

    public partial class SimpleWinControl : UserControl
    {
        public SimpleWinControl()
        {
            InitializeComponent();
        }
    
        public Button TheButton { get { return button1; } }
    
        ...
    }
    

    Give the WinForms control an x:Name in your XAML markup:

    <WindowsFormsHost HorizontalAlignment="Left" Height="Auto" Margin="87,43,0,0" VerticalAlignment="Top" Width="Auto">
        <local:SimpleWinControl x:Name="winFormsControl" />
    </WindowsFormsHost>
    

    ...and hook up to the Click event of the Button in the code-behind of your WPF dialog window:

    public partial class Dialog : Window
    {
        public Dialog()
        {
            InitializeComponent();
            winFormsControl.TheButton.Click += (s, e) => this.Close();
        }
    }
    

    The window that opens the dialog could then access the importantdata field once the ShowDialog method returns:

    private void ShowDialog_Click(object sender, RoutedEventArgs e)
    {
        Dialog d = new Dialog();
        d.ShowDialog();
    
        object importantData = d.winFormsControl.importantdata;
    }
    

    Another option may be to raise an event from the WinForms control: https://msdn.microsoft.com/en-us/library/5z57dxz2(v=vs.90).aspx