Willy
Willy

Reputation: 10660

Casting to ElementHost not possible?

I have an VSTO Outlook Add-in (a kind of winforms app) and I am using an Outlook control that allows embedding a custom winforms user control.

Instead I want to embed an WPF user control so I create a Winforms user control and place within it an ElementHost. Finally I embed the WPF user control within the ElementHost.

So the structure is:

  VSTO Outlook Add-in <---> Outlook Control <---> Winforms User Control <----> ElementHost <----> WPF user control

Now from my WPF user control, from its code-behind (*.xaml.cs) I am trying to access a method hosted in the winforms user control so I do below:

ElementHost eh = (ElementHost) this.Parent; <----- error
MyWinformUserControl winformUC = eh.Parent;
winformUC.MyMethod();

When trying to cast to ElementHost I get a compilation error that says:

CS0030: Cannot convert type 'System.Windows.DependencyObject' to 'System.Windows.Forms.Integration.ElementHost'

If I change to:

ElementHost eh = this.Parent as ElementHost;

then compiler says:

CS0039: Cannot convert type 'System.Windows.DependencyObject' to 'System.Windows.Forms.Integration.ElementHost' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion.

So how can I cast into an ElementHost?

Upvotes: 1

Views: 106

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125322

Assuming you have a MyWinFormsControl which has a DoSomething method, you can call it from WPF like this:

public partial class MyWPFControl : UserControl
{
    public MyWPFControl()
    {
        InitializeComponent();
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var hwnd = PresentationSource.FromVisual(this) as HwndSource;
        var host = System.Windows.Forms.Control.FromChildHandle(hwnd.Handle) as ElementHost;
        var myUC = host.Parent as MyWinFormsControl;
        myUC.DoSomething();
    }
}

However, I'd suggest you revert the dependency and pass whatever you need to the WPF control. It could be passing the whole control, could be passing a delegate, or could be raising an event in the WPF control and handling in WinForms control.

public partial class MyWPFControl : UserControl
{
    public MyWPFControl()
    {
        InitializeComponent();
    }
    public MyWinFormsControl Control { get; set; }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Control.DoSomething();
    }
}

And here is MyWinFormsControl

public partial class MyWinFormsControl : UserControl
{
    public MyWinFormsControl()
    {
        InitializeComponent();
        ((MyWPFControl)elementHost1.Child).Control = this;
    }
    public void DoSomething()
    {
        MessageBox.Show("Hi");
    }
}

Upvotes: 1

Related Questions