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.
Related
I have spent countless hours reading and researching this topic – and I just can’t seem to get a foothold on it. Here is my scenario:
I write software for a company that provides asset-tracking (with some added features). We currently have an ASP.NET based website using the googlemaps api. So this is what I am comfortable with.
I have now been tasked with writing a WPF application with much of the same functionality but instead using the wpf bing maps api.
I have messed around with the map and figured out (non-mvvm way) how to draw custom pushpins, polygons, etc… Now I need to use the databinding features. This is where I just can’t seem to put the two together. Basically what I am trying to do is bind a collection of a custom class that creates a custom pushpin, to a MapControlItem.
The documentation is just a bit too fragmented and abstract for me to grab on to something – or maybe I am just too much of a web developer and really struggling to grasp a concept that is new to me.
Any ideas? Examples?
You're right, the Bing Maps WPF Control API documentation is a joke.
Anyway, you would have to use a MapItemsControl and bind its ItemsSource property to your item collection. The ItemsContainerStyle and/or ItemTemplate properties would define the UI objects that are shown on the map.
You may start reading about Data Binding to Collections.
I only played with the Windows 8 version of the Bing maps control, not the WPF one, so I apologize if my answer is not quite apropriate.
What I know, is that in windows 8, you just can't apply bindings, for MapLayers or MapChildren.
From what you describe, I believe you just can't do a binding on these properties in WPF, simply because they are not dependency properties.
So only 1 solution left, in you window's code-behind, subscribe to your ViewModel's PropertyChanged event, and manually apply any updates you need to your control.
Anoter way to do that, is to create a UserControl, which will simply display a BingMaps control, and add to this userControl a "BingMapsContext" (or whatever) dependency property, to manually update the map control when that specific property will be binded.
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.
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.
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).
Specifically in MVVM Light toolkit? I've not dove into the Prism code yet to see what it does in regard to regions in a WPF UI. Seems like with the messaging and the ViewModelLocator in MVVM Light you could do a similar thing....Can you? Can anyone give some examples on how you could do this? Essentially I'd like to click on a button and load two different view models into the UI. Perhaps a better way to explain is Outlook-like Navigation Pane functionality.
This can be done fairly easily in WPF, without any framework.
Just setup a DataTemplate in your Application (or at the Window/UserControl level) that maps the ViewModel to the View you wish to display for that ViewModel.
You can then just use a ContentPresenter, and bind it's contents to a single property (which can be of type object) within your ViewModel. When you want to set the "region" to a specific View, just set the property to the appropriate ViewModel, and WPF will automatically wire up everything for you.