WPF MVVM pattern

You can explain the implementation of this pattern in detail, simply and clearly. I've already reread a lot of literature on this topic. I understand the essence, but when it comes to implementation, there is a dead end, I do not know how to properly organize the model and ViewModel. With the view, everything seems to be more or less clear(the xaml file is our application appearance). Here for example I have a couple of conditional classes:

public class Test
    {
        private string testName;
        public string TestName
        {
            get { return testName; }

           set
            {
                testName = value;
            }
        }

        public List<Question> QuestionList = new List<Question>();

        public List<Answer> AnswerList = new List<Answer>();

        public int Time { get; set; }

        public int QuestCount { get; set; }
    }


 public class Question
    {
        public int ID { get; set; }
        public string Text { get; set; }

    }

 public class Answer{
        public int ID { get; set; }
        public int VariantID { get; set; }
    }

I understand this is the data model, but here's the question, does this class have lists answers and questions, which are also objects of the same name classes. Separate them into separate models each, and then combine them into a ViewModel or what? And how to organize the ViewModel itself? I would be very grateful for an explanation.

Author: Ага, 2018-04-22

1 answers

The model is logic + data. That is, ideally, all business logic should work only in this layer and should not know anything about its display. In other words, write a console application - fully functional, just do not write all sorts of console inputs and outputs - and already wrap the viewmodels and views on top.

So yes - all models will have to be wrapped in viewmodels.

Let's define a base class for viewmodels:

public class ViewModelBase: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

Then the viewmodel for Question will be:

public class QuestionViewModel : ViewModelBase
{
    private Question _question;
    private int _id;
    private string _text;

    public QuestionViewModel(Question question)
    {
        _question = question;
    }

    public int Id
    {
        get { return _question.ID; }
        set { _question.ID = value; OnPropertyChanged(); }
    }

    public string Text
    {
        get { return _question.Text; }
        set { _question.Text = value; OnPropertyChanged(); }
    }
}

Let's say you have a collection QuestionModelsCollection from the database or from somewhere else

Then in the form model there will be a collection

 public ObservableCollection<QuestionViewModel> Questions {get;set;}

And it can be initialized somehow like this:

Questions = new ObservableCollection<QuestionViewModel>(QuestionModelsCollection.Select(x=> new QuestionViewModel(x));

To this already link the view. Naturally, the pattern is not a law, but a recommendation, it does not always make sense to separate - when you need to display some static information - over which there will be no manipulations - you can also link a raw collection of models. In addition, it is one of the many ways. According to the situation, we need to look at how it will be better in this or that case.

So, we have a problem with nested models.

For example, we will have this model:

public class Question
{
    public string Text { get; set; }
    public List<Answer> Answers {get;set;}
}

Then:

public class QuestionViewModel : ViewModelBase
{
    private Question _question;
    public ObservableCollextion<AnswerViewModel> Answers{get;set;}

    public QuestionViewModel(Question question)
    {
        _question = question;
        Answers = new ObservableCollection<AnswerViewModel>(_question.Answers.Select(x=> new AnswerViewModel(x));
    }

    public string Text
    {
        get { return _question.Text; }
        set { _question.Text = value; OnPropertyChanged(); }
    }
}
 3
Author: srvr4vr, 2018-04-22 14:08:46