Модель Windows Forms (WinForms) Отобразить шаблон ViewModel (MVVM) в DataBind или нет - PullRequest
7 голосов
/ 01 октября 2010

Во-первых, я не злюсь, потому что я использую MVVM в WinForms-). Я знаю о шаблоне MVP (Model View Presenter) и его вариантах. Когда я начинал этот проект, я собирался изучить WPF и использовать его, но я вынужден спешить с разработкой программы, и у меня нет времени изучать WPF, поэтому я должен написать его в WinForms, который я хорошо знаю.

Итак, вкратце, у меня есть большое интеллектуальное клиентское приложение, ориентированное на данные, которое почти готово, у меня есть все модели и ViewModel (инфраструктура, домен, презентация завершены), пользовательский интерфейс тоже готов, теперь мне нужно только подключить интерфейс к ViewModels.

Сначала я начал подключать его стандартным способом winforms (BindingSources и простым связыванием данных), но когда я сделал 30-50% привязки, я обнаружил, что моя программа работает очень медленно, у меня примерно 100-150 связанных свойств, поэтому 30 из них являются привязками корневого объекта домена (агрегатного корня) к его EditForm. Таким образом, привязка данных не работает хорошо в этой ситуации, множество ненужных обновлений, каскадные обновления всего представления, когда что-то меняется незначительно, неясное поведение и другие уродливые вещи. Он пахнет очень ненадежным кодом, над которым у меня мало контроля.

Поэтому я начал переписывать проводку как чистый чистый код WinForms (подписка на события PropertyChange и ListChanged и установка свойства ViewModels самостоятельно из пользовательского интерфейса). Много кода для написания, но он работает намного быстрее, у меня есть полный контроль над этим, и он чувствует себя намного надежнее.

Так что ты думаешь об этом парне? У кого-нибудь был такой опыт? Какой у вас вердикт по поводу «Связать данные или нет»?

Ответы [ 3 ]

6 голосов
/ 01 октября 2010

Возможно, вы захотите взглянуть на Ферма .Он предоставляет менеджер связывания в стиле WPF, который работает с POCO.Это делает использование MVVM с Windows Forms намного более эффективным.

1 голос
/ 31 марта 2014

Другая возможность заключается в использовании унаследованного компонента BindingSource для привязки данных в WinForms.Например: http://ingebrigtsen.info/2010/08/31/mvvm-in-windows-forms/. Он работает гладко даже в средах NET CF.

Я изменил реализацию для достижения двух целей:

  • простая поддержка привязки данных для моих моделей представлениячерез конструктор WinForms
  • поддержка многопоточности с control.Invoke, потому что BindingSource по умолчанию не поддерживает его.Теперь он реагирует на события PropertyChanged из фонового потока.

Вот мой простой класс ViewModelBindingSource:

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 голос
/ 28 ноября 2010

Использование привязки данных в WinForms является действительно болезненным, и подписка на события INotifyPropertyChanged и выполнение действий вручную является излишним.Мне действительно нравится MVVM даже на WinForms за его отличную тестируемость и удобство обслуживания, но не за цену, в 3 раза превышающую количество написанного кода.Так что для нового кода я использую сейчас комбинированный View + ViewModel.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...