Using WPF, MVVM and Bindings with WinForm UserControl, how to integrate successfully?

I have a WinForm UserControl inside a WPF window, and WPF code uses the MVVM pattern.

What is the best way to successfully integrate a WinForm control into an MVVM template? Is it possible to use some form of binding from the side of WPF?

Let's say that I want to handle some events from the WF control, is there a way to completely switch to MVVM?

Thanks.

+4
source share
3 answers

Personally, I would handle this by creating a WPF UserControl that wraps the Windows Forms control. This will allow you to encapsulate all the necessary code in your WPF control, and then use it in its pure form MVVM.

It will be difficult to remain โ€œcleanโ€ MVVM directly with the Windows Forms control, since managing Windows Forms usually requires a different binding model, and also usually requiring direct event handling.

+1
source

Please note that this does not answer the questions (I should have read better). If you are interested in using the WPF control in a WinForms application, then this is the approach. My scenario: 1) Have a WinForms control that is used in many places in my application. 2) Want to develop a WPF implementation that will use the MVVM pattern. 3) Want to write a control as the right WPF control complete with dependent properties so that it can be used correctly when my application, ultimately, all WPF. 4) You want the same WinForms control and API not to violate the existing client code in my application.

In most cases, everything was simple, except that my WinForms managed events when changing the properties of my WPF control. I wanted to use binding, but since the source of the binding should be DependencyObject, and System.Windows.Forms.UserControl should not, I had to create a simple nested class. I wrote my WPF control in the same way as if I integrated it into a WPF application and just did some extra thunking to get my WinForms shell working.

Here is the code for my WPF control:

public partial class MonkeySelector : UserControl { public static readonly DependencyProperty SelectedMonkeyProperty = DependencyProperty.Register( "SelectedMonkey", typeof(IMonkey), typeof(MonkeySelector)); public MonkeySelector() { InitializeComponent(); } protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); // Note: No code is shown for binding the SelectedMonkey dependency property // with the ViewModel SelectedMonkey property. This is done by creating // a Binding object with a source of ViewModel (Path = SelectedMonkey) and // target of the SelectedMonkey dependency property. In my case, my // ViewModel was a resource declared in XAML and accessed using the // FindResource method. } public IMonkey SelectedMonkey { get { return (IMonkey)GetValue(SelectedMonkeyProperty); } set { SetValue(SelectedMonkeyProperty, value); } } } 

Here is the code for managing WinForms:

 public partial class WinFormsMonkeySelector : UserControl { public event EventHandler SelectedMonkeyChanged; private MonkeySelector _monkeySelector; private WpfThunker _thunker; public WinFormsMonkeySelector() { InitializeComponent(); _monkeySelector = new MonkeySelector(); _elementHost.Child = _monkeySelector; System.Windows.Data.Binding binding = new System.Windows.Data.Binding("SelectedMonkey"); binding.Source = _monkeySelector; binding.Mode = System.Windows.Data.BindingMode.OneWay; _thunker = new WpfThunker(this); // Note: The second parameter here is arbitray since we do not actually // use it in the thunker. It cannot be null though. We could declare // a DP in the thunker and bind to that, but that isn't buying us anything. System.Windows.Data.BindingOperations.SetBinding( _thunker, MonkeySelector.SelectedMonkeyProperty, binding); } protected virtual void OnSelectedMonkeyChanged() { if (SelectedMonkeyChanged != null) SelectedMonkeyChanged(this, EventArgs.Empty); } public IMonkey SelectedMonkey { get { return _monkeySelector.SelectedMonkey; } set { _monkeySelector.SelectedMonkey = value; } } private class WpfThunker : System.Windows.DependencyObject { private WinFormsMonkeySelector _parent; public WpfThunker(WinFormsMonkeySelector parent) { _parent = parent; } protected override void OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); // Only need to check the property here if we are binding to multiple // properties. if (e.Property == MonkeySelector.SelectedMonkeyProperty) _parent.OnSelectedMonkeyChanged(); } } } 
+2
source

You might look at the WAF Windows Forms Adapter . It shows a possible way to use Windows Forms with MVVM.

0
source

Source: https://habr.com/ru/post/1347142/


All Articles