Embed threaded WindowsFormsHost in WPF - c#

I have a WPF application and an ActiveX control that gets embedded into the WPF application using a WindowsFormsHost control.
The ActiveX control is used to communicate with an external application that draws 3D contents into the control.
One big issue of this setup is that if the ActiveX control does some long running operations, the rest of the WPF application gets blocked.
I would like to solve this issue and somehow prevent the ActiveX control to be hosted on the same thread as the remaining controls in my UI.
I searched for possible solutions and found this article:
https://blogs.msdn.microsoft.com/dwayneneed/2007/04/26/multithreaded-ui-hostvisual/
Unfortunately I cannot use this sample to host a WindowsFormsHost element as it is not derived from Visual.
The only other option I could implement so far is to host the ActiveX control inside a separate window which I launch on a separate thread.
Although this works it is quite messy to manage as I have to manually snap the separate window to the main window to get kind of a uniform layout.
Is there anything else I can try to achieve a single-window experience but also having the ActiveX control hosted on a separate thread?

Related

WPF controls hosted on Winforms application stop updating

I have a legacy Winform application (quite large and monolithic) where we now host WPF controls for the newer functionality.
After some interaction and updating, I get it into a state were all the WPF controls (only) stop updating. Ie if I set a property in the bound view model, the UI does not update. Also controls such as splitters and sliders do not work. Event if I invoke a WPF dialog, the radio button on it does not work.
All the Winforms controls work fine. It is although there is some WPF layer that has stopped functioning.
I have checked everything I can think of, ie everything occurring on correct threads, rendering in SoftwareOnly etc. Pausing the application, I see no locked threads, or anything else suspicious. I don't see any exceptions.
I am now at a loss on how to diagnose what is wrong here.
Does anyone have any ideas on how I can diagnose such an issue? Ie is there anything common like this that can occur with WPF on Winforms? I have never come across this before!
Thanks in advance for any help here.
[UPDATE1]
I just noticed, if I resize the WPF winforms parent container, THEN the WPF control updates..

How to refresh WPF AutomationElement with DataTemplate - Windows UI Automation

I am trying to automate the testing of a WPF application using Windows UI Automation.
The application has a ContentControl with a data template that changes based on user interaction.
On initial load, I am able to get and click a button inside of the content control. This switches the data template (the sub-controls are removed and replaced with other ones).
However, when I look for the new controls in the automation element, they cannot be found.
I am using the wrapper FlaUI, but I've also tried White and they both have the same sort of result.
I am not using caching, but it seems like the window is somehow cached. Is there a way to reload the element or entire window so that I can retrieve the new controls.
Found the solution on FlaUI's FAQ.
When using DevExpress controls, some things (like tab content) are not
updated By default, DevExpress controls do not raise automation
events, as these events may decrease the application performance. To
make sure that the events are raised properly, set the
ClearAutomationEventsHelper.IsEnabled static property to false on
application startup (needs to be done in the application that is
automated with FlaUI):
ClearAutomationEventsHelper.IsEnabled = false;

WPF User Control in WinFORMS: Project Structuring

SCENARIO
I decided to work on WPF technology for my new application. This application has to be called on Menu click from a WinForms window. So I created a WPF UserControl Library and integrate it to display in parent WinForms Form using Element Host.
My Application
It contains 3 child usercontrols which are encapsulated inside another usercontrol with tabContent Control. I prefered this approach as firing events from Child UserControl and handling in WinForms (subscribing events) seemed painful.
My Question
Now facing the same painful task of accessing UserControl elements inside Winforms where I have created Data Manager class for proper project structuring reasons (UserControl should not contain Data Manager class-UI). Please guide me as to how to structure my project/how to subscribe events/access WPFUserControl elements inside WPF.
Take a look at the Messenger class of MVVM Light Toolkit (can also be used standalone). It helps decoupling your controls. The messenger works with a publish/subscribe pattern. Your WPF UserControls can publish objects, the WinForms Host can listen on those notifications. The exchanged messages (objects) are best placed in separate assembly, as they define the shared contract between WPF UC-library and WinForms application.

Re-parenting ActiveX Control

Is it possible in WPF to move an ActiveX control to a different place in the visual tree? I have a control that I would like to dynamically move to be the child of another widget.
If this isn't possible is there a way to make a copy of the control and place it somewhere else? My previous attempts at this have not worked at all.
Here is an analogy, it's not a great one, but hopefully it drives the point home:
Imagine you have built a scene up using LEGOs. You also have a flat piece of aluminum with an image on it and you want to insert it under one of your LEGO layers so that it becomes part of the scene. You can't do this because there are no pegs and holes in the aluminum. It wont stick to the bottom layer and the LEGOs on top won't stick.
The analogy breaks down here because in the real world you could use glue or something to make it work.
WPF provides a single window object hosting a single DirectX surface upon which it renders each of its controls (our LEGOs above). ActiveX controls (or Winforms controls) each require a separate system window object (the aluminum plate). It's not possible to place a system window in between elements rendered on a DirectX surface.
The two technologies don't mix (or at least don't intermingle). You either have to live with this fact and arrange things with that limitation, or you need to change technologies. Either build your application with Winforms (where every control is a system window), or create/find a WPF control that provides the same functionality as this ActiveX control you're using.

WPF used within a WinForms application, where to put Application resources?

At present we host a number of WPF controls in a WinForms application. The application is started using the System.Windows.Forms.Application.Run(...) method and WPF controls hosted using the ElementHost.
In a normal WPF application I'd define a System.Windows.Application object (App.xaml) and call run on it. Normally any application level WPF resources would go in there. We don't have this.
How can I specify application level resources for the WPF controls but still run as a WinForms app?
In a hosted environment you do not have easy access to the Application, Dr WPF has a couple of methods for working in a hosted scenario at http://drwpf.com/blog/2007/10/05/managing-application-resources-when-wpf-is-hosted/.
I am personally using his SharedResources class in a work project, VB6 Form hosting Winforms UserControl hosting ElementHost hosting WPF UserControl with a Application wide theme, for the WPF controls.
If you host WPF controls within a WinForms application you do not have the Applicationobject which hosts the application-wide resources. The trick is to create such a object, load your global resources and merge them into the ResourceDictionary.
Here is an example of this code:
http://www.snippetsource.net/Snippet/26/load-application-level-resources-in-winforms-hosted-wpf-controls (Link fixed)

Categories