Changing dependency property(in ViewModel) hosted to Winform - wpf

I have WinForm application with hosted in it WPF(mvvm) part. Is it possible to change dependency property in ModelView from my WinForm ?

Is it possible to change dependency property in ModelView from my WinForm ?
It is - but your Windows Forms portion would need to understand the WPF types to do it. You can always use the wrapper defined when implementing a dependency property to call it from code.
If you're hosting a Windows Forms control, however, you'll likely want to make a WPF wrapper that subscribes to the appropriate events on the control, and uses them to set the dependency property. This way, your Windows Forms portion stays "pure" and doesn't need modification, and your WPF portion can set everything appropriately.

Related

Access VB6 parent form's AmbientProperties.UserMode property from interop UserControl

Is there a way by which a WinForms interop UserControl hosted on a VB6 form can retrieve the parent form's AmbientProperties.UserMode value?
The UserControl's DesignMode property is false, which makes sense given that the control has been compiled and registered.
This is such an interesting question.
According to this (https://learn.microsoft.com/en-us/windows/win32/com/ambient-properties), all ActiveX Control Containers must support the UserMode Ambient property.
Try using InvokeMember to call the UserMode property via IDispatch (https://learn.microsoft.com/en-us/dotnet/api/system.type.invokemember?view=netframework-4.8).

Binding winform control property in XAML

We are currently in the process of switching our product from WinForms to WPF. At the moment we are using some 3rd party WinForm controls that are required for our application. Even though we plan to eventually replace them with WPF versions, right now this is not possible. We've tried hosting them in the wpf window inside WindowsFormsHost control, and it seems to work just fine. The only problem we have is how to pass our data from VM to these controls. We would like to avoid any code-behind and alterations to VM just to accomodate this controls. Ideally, we would prefer to keep VM completely unaware of the controls used to display it's data, so that when we do change to WPF version of these controls, we only need to modify the view. This is why we're looking for a way to bind VM property to hosted WinForm control from XAML. If this helps, we can certainly live with the fact that there is only a one way binding from VM to the control, and we don't mind if the binding works only once, without the subsequent updates from VM, since the VM properties we are binding do not change. Perhaps someone has any ideas how we can make this happen?
Not sure if there is a better way, but here's one idea:
Wrap your WinForm control/WindowsFormsHost control into a wrapper control (inherit from Control or use a UserControl, whatever is best for you).
On this wrapper you can add dependency properties that you want to bind to your VM.
Inside the wrapper code, you can add the boilerplate required to propagate changes back and forth between your wrapper dependency properties and your winform properties.
This hides the dirt under the carpet and exposes a nice WPF facade that you can bind to as usual, without changing your VM.
When the control is phased out, remove the wrapper from your project and you can bind the VM directly to the new WPF replacement control.

How to implement two way binding between an ActiveX control and a WPF MVVM View Model

I have a WPF application implemented using the MVVM framework that uses an ActiveX control and I need to keep the WPF and ActiveX UI synchronised.
So far I can update the ActiveX UI when I change the WPF UI using the code at the bottom of the question that I got from the article Hosting an ActiveX Control in WPF and this question.
But I cannot update the WPF UI when I make a change in the ActiveX UI.
I suspect that I need to fire the PropertyChanged event from my ActiveX control but I have no idea how to do this or if it is even possible.
The ActiveX controls I have written are in VB6 and MFC as I am just prototying at this time for the eventual integration of VB6 ActiveX controls in a WPF contaner application.
Here is a code snipet that indicates the work done so far:
System.Windows.Forms.Integration.WindowsFormsHost host = new System.Windows.Forms.Integration.WindowsFormsHost();
// Create the ActiveX control.
AxTEXTBOXActiveXLib.AxTEXTBOXActiveX axWmp = new AxTEXTBOXActiveXLib.AxTEXTBOXActiveX();
// Assign the ActiveX control as the host control's child.
host.Child = axWmp;
axWmp.DataBindings.Add(new System.Windows.Forms.Binding("ActiveXStatus", (MainWindowViewModel)this.DataContext, "ModelStatus", true, DataSourceUpdateMode.OnPropertyChanged ));
// Add the interop host control to the Grid
// control's collection of child controls.
this.activexRow.Children.Add(host);
How to implement two way binding between an ActiveX control and a WPF MVVM View Model?
What you need to do is create an ActiveX library that both the ActiveX control can refer too and the WPF assembly. In the library create an interface with a refresh method of whatever complexity you need. Create a global multi-use method that objects that implement can use to register themselves. Then in the ActiveX control it can check to see whether anything been registered and fire the refresh method. Then in the WPF Assembly the UI can implement the interface and register itself supplying the connection between it and the ActiveX Control.
You're going to have to find some way of notifying WPF that data in the ActiveX control has changed. This is usually handled in WPF by implementing INotifyPropertyChanged or using ObservableCollections. Just binding a property doesn't update the UI for WPF either, try binding something in your view to a property on the viewmodel and not using INotifyPropertyChanged. If you have control of the activex source this should be easy to do using events.

Best way to set CurrentCulture so it applies to all WPF components

I've just learnt to my surprise that WPF doesn't use the CurrentCulture for bindings, instead defaulting to en-US.
In a pure WPF application, this can be fixed in one place by setting the language globally once in the App class.
However I have a WinForms application that is being progressively migrated to WPF, and contains several WPF UserControls. What's the best/simplest way to ensure the CurrentCulture is used for all UserControls? Do I really have to make all my UserControls inherit from a base class that does this, or is there some way to set it globally?
You can use a slightly different approach and derive once from ElementHost and manipulate your WPF UserControl instances as they are instantiated. For example, you can create a LocalizingElementHost with a ChildChanged event handler that does to the child what you would have done in a base class.
You can still use the same approach with LanguageProperty.OverrideMetadata, just put it at the beginning of your program (Main method).

Using ActiveX control in WPF

I'm attempting to host an ActiveX control in a WPF app. After attempting to use existing info on the web and here, I've hit a dead-end.
I need to use an ActiveX control provided to communicate with a UV power meter. They provide an application that registers and uses the control and even includes some useful demo apps. I stripped out the OCX file and put it here if needed. You won't have the power meter to talk to, but the app and demos will still load the ActiveX control successfully.
I created a simple Windows Forms application. I was able to bring the ActiveX control into the toolbar, drop it into my form, and everything is fine. The demo apps they provide do this as well.
However, getting this to work in a WPF environment is another story. The control can't be added to the toolbox and "dragged" into the app.
So far I've tried two techniques:
Technique found here. I am able to add a reference to the control, but then I enter namespace hell. The xmlns:ax namespace it suggests making cannot find the information. Here's my attempt based on what the object viewer tells me: xmlns:ax="clr-namespace:OphirUsbXLib;assembly=Interop.OphirUsbXLib"
Technique found here. This is essentially to create a new project that creates a library based on Windows Forms, which contains the ActiveX control (yikes). I am able to add the Windows Forms Host, but I cannot get access to the ActiveX control within. I can make the control public, but I still cannot call methods etc. This doesn't look like the right solution.
In short, I have an ActiveX control that works beautifully in Forms, but is a real bitch to get working in WPF.
Any insight is appreciated!
In this situation I would consider making a WinForms usercontrol which wraps the ActiveX control you are trying to use.
You could make public properties and methods which expose each of the required properties and methods on the ActiveX control, and then host this WinForms UC on the in a WPF WinFormsHost control.
I have already done something similar to this, in reverse, hosting a WPF UserControl in a WinForms UserControl, then hosting that on a VB6 Form in a legacy application.

Resources