samedi 14 avril 2018

C#, WInForms: Propagate changes to a list in a MVVM

I am trying to build a simple C#/WinFoms project that uses the Model-View-ViewModel design pattern according to the structure:

enter image description here

The data binding between the two UserControls and the associated ViewModels does not work well.

The MainForm contains two UserControls (UC): Uc_Create, Uc_Iteration. Each UC contains a combobox that is connected to the associated property in the ViewModel_xxx, namely

Uc_Create has:

this.comboBox1ComplexCreate.DataSource = oVM_Create.VM_Create_ListOfStringsInModel; 

Uc_Iteration has:

this.comboBox1ComplexIteration.DataSource = oVM_Iteration.VM_Iteration_ListOfStringsInModel;

The problem:

When I add elements to VM_Iteration_ListOfStringsInModel the combobox in the corresponding (comboBox1ComplexCreate) and the list in the Model are correctly changed but the other combobox (comboBox1ComplexIteration) in Uc_Iteration
is not!

Why????

If I change the List in the Model to a BindingList, everything works fine. What am I doing wrong?

Thanks in advance!


Model:

namespace Small_MVVM
{

    public class Model 
    {
        private static readonly object m_oLock = new object();

        private static Model instance;


        public List<string> simplelistOfStrings; 

        private Model()
        {
            simplelistOfStrings = new List<string>();
        }

        public static Model GetInstance()
        {
            if (instance == null)
            {
                lock (m_oLock)
                {
                    if (instance == null)
                    {
                        instance = new Model();
                    }
                }
            }
            return instance;
        }
    }
}

ModelView_Create:

namespace Small_MVVM
{
    class ViewModel_Create : NotifyPropertyChangedBase
    {
        private static Model oModel = Model.GetInstance();

        private BindingList<string> _VM_Create_ListOfStringsInModel = new BindingList<string>(oModel.simplelistOfStrings);
        public BindingList<string> VM_Create_ListOfStringsInModel
        {
            get
            {

                return _VM_Create_ListOfStringsInModel;
            }
            set
            {
                _VM_Create_ListOfStringsInModel = value;
                this.FirePropertyChanged(nameof(VM_Create_ListOfStringsInModel));
            }
        }
    }
}

ModelView_Iteration:

namespace Small_MVVM
{

    class ViewModel_Iteration : NotifyPropertyChangedBase
    {
        private static Model oModel = Model.GetInstance();

        public ViewModel_Iteration()
        {

        }

        BindingList<string> _VM_Iteration_ListOfStringsInModel = new BindingList<string>(oModel.simplelistOfStrings);
        public BindingList<string> VM_Iteration_ListOfStringsInModel
        {
            get
            {
                return _VM_Iteration_ListOfStringsInModel;
            }
            set
            {
                _VM_Iteration_ListOfStringsInModel = value;
                this.FirePropertyChanged(nameof(VM_Iteration_ListOfStringsInModel));
            }
        }
    }
}

This is the abstract class NotifyPropertyChangedBase

public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    protected bool CheckPropertyChanged<T>(string propertyName, ref T oldValue, ref T newValue)
    {
            if (oldValue == null && newValue == null)
        {
                return false;
        }

        if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue))
        {
            oldValue = newValue;
            return true;
        }

        return false;
    }

    private delegate void PropertyChangedCallback(string propertyName);

    protected void FirePropertyChanged(string propertyName)
    {
         if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Aucun commentaire:

Enregistrer un commentaire