Windows Forms (WinForms) View Model ViewModel (MVVM) model for DataBind or not

At first I am not angry because I use MVVM in WinForms.) I know about the MVP (Model View Presenter) template and its variants. But when I started this project, I was going to learn WPF and use it, but I have to rush to develop the program and I do not have time to learn WPF, so I have to write it in WinForms, which I know well.

So, I have a big data-oriented application for intelligent clients, which is close to the end, I have all the models and ViewModels made (infrastructure, domain, presentation). The user interface is also done, now I only need to connect the interface to ViewModels. At first I started connecting to it using the standard winforms method (BindingSources and simple data binding), but when I did 30-50% of the binding, I found out that my program is very slow, I now have 100-150 related properties, 30 of they represent the root entity of the domain (aggregate root) of the EditForm binding to it. Thus, data binding does not work very well in this situation, a lot of unnecessary updates, cascading updates of the whole view, when some small changes, fuzzy behavior and other ugly things happen. It smells like very unreliable code, on which I have little control. So I began to rewrite transactions as pure, clean WinForms code (by subscribing to the PropertyChange and ListChanged events, and setting the ViewModels property from the user interface myself). A lot of code to write, but it works much faster, I have full control over this, and it feels much more reliable. So what do you think of these guys? Has anyone had such an experience? What is your verdict "In DataBind or not"?

+7
c # data-binding winforms mvvm
source share
3 answers

Using data binding in WinForms is really painful, and subscribing to INotifyPropertyChanged events and performing manual actions is an excess. I really like MVVM even on WinForms, because it is excellent testability and maintainability, but not at a price 3 times more than the code for writing. Therefore, for the new code, I now use the combined View + ViewModel.

+1
source share

You might want to take a look at Truss . It provides a WPF-style binding manager that works in POCOs. This makes using MVVM with Windows Forms much more efficient.

+6
source share

Another possibility is to use the legacy BindingSource component to bind data in WinForms. For example: http://ingebrigtsen.info/2010/08/31/mvvm-in-windows-forms/ . It runs smoothly even in the NET CF environment.

I changed the implementation to achieve two goals:

  • simple data binding support for my ViewModels model through WinForms constructor
  • multithreading support with control.Invoke, because BindingSource does not support it by default. Now it is responding to PropertyChanged events from the background thread.

Here is my simple ViewModelBindingSource class:

public class ViewModelBindingSource : BindingSource { private readonly Control _control = new Control(); private object _viewModel; private Type _viewModelType; public ViewModelBindingSource() { } public ViewModelBindingSource(IContainer container) : base(container) { } public ViewModelBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember) { } public object ViewModel { get { return _viewModel; } set { _viewModel = value; } } public Type ViewModelType { get { return _viewModelType; } set { if (value != null) { // save the type of our viewmodel _viewModelType = value; // create an instance of our viewmodel - so we don't need codebehind _viewModel = Activator.CreateInstance(_viewModelType); // add the viewmodel instance to the internal IList collection of the bindingsource Add(_viewModel); // move to the first element MoveFirst(); // set the datasource of the binding source to the first element // this is necessary for data binding of all windows forms controls DataSource = this[0]; } } } /// <summary> /// Pass the call to the main thread for windows forms /// This is needed for multithreading support. /// </summary> /// <param name="e"></param> protected override void OnListChanged(ListChangedEventArgs e) { if (_control != null && _control.InvokeRequired) _control.Invoke(new Action<ListChangedEventArgs>(OnListChanged), e); else { base.OnListChanged(e); } } 
+1
source share

All Articles