An analysis of the relationship between commands and delegates in the MVVM mode in WPF

Source: Internet
Author: User

?? Hello friends Everyone, I am Payne, welcome to pay attention to my blog, my blog address is http://qinyuanpei.com. Recently, because of the reasons for the project to start contacting WPF, perhaps this is now out of date, I guess people will not be interested to understand, but you do not understand that for some conservative projects, security is more important than the advanced, so when you find that banks such institutions are still using a variety of "retro" software system , you should believe that this kind of thing has the meaning of their existence. At the same time, you will have a deeper understanding of the truth: whether technology is advanced and its popularity is not directly related to itself. From this we can infer that a non-popular technology is not necessarily because it is not technologically advanced, perhaps simply because it does not meet the needs of commercialization. I'm really saying here that WPF,MVVM thought was first proposed by WPF, However, it is because the front-end field in recent years more hot angularjs and vue.js, we expressed here is: a lot of ideas you think very trendy, perhaps just by people re-given the new name, when you clear the context of all this, you will find that it is not different. This is in line with my usual claim: to find out the nature of the problem, not to be bound by the framework, to eliminate differences through commonality, so in this article today, I want to talk about the relationship between commands and delegates in the MVVM mode in WPF.

What is MVVM?

?? Now that we're referring to MVVM, there's an inevitable need to know what MVVM is. As we have mentioned at the beginning of this article, the concept of MVVM was first proposed by Microsoft, specifically by Microsoft architect John Gossman. I personally prefer to enhance understanding by comparing MVC, MVP, and MVVM in a way that is, in a sense, a process of gradual improvement and evolution. We often talk about the three-tier architecture of software, which we often use to divine MVC, but in fact they are some kind of idea that is infinitely close to the mind.

?? First, we start with the simplest MVC, and as one of the most common software architectures, we can see from the diagram above that MVC is actually a very simple concept, which consists of a model, a view, and a controller that are three parts. Based on a unidirectional flow of communication, the view notification controller responds to a user request, and the controller updates the data in the model after receiving a notification from the view, and the model feeds the new data to the view. We have found that this design allows for separation of concerns in software engineering, and we note that through the MVC pattern, we realize the separation of views and models, through which the glue layer of the controller makes the two indirectly connected, so the advantage of MVC is that the various modules better collaborate. So, what is its disadvantage? Obviously, the view and the controller are highly coupled, because the controller inevitably accesses elements within the view, so the controller is destined not to be immune from this earthly world. To know that the first MVC architecture was implemented based on the observer pattern, that is, when the model changes, the view and controller are notified at the same time, so we can quickly realize that all our efforts since ancient times have been to separate the views and models from each other, and we are going further and farther down this road, Fortunately, I have never forgotten beginner's mind.

?? Next, in order to completely separate the view from the model, we invented the new software architecture: MVP. Although from the perceptual understanding, it is to change controller to presenter, but from the rational understanding, it is to let the view and model separation this matter more resolute. From the diagram we can see that the view and model no longer have direct contact, they are connected through presenter, and the communication between the parts has become two-way flow. We can quickly realize that the new controller, presenter, will become more and more "heavy", because all the logic is here, and the view becomes more and more "light", it no longer needs to take the initiative to get the data provided by the model, it will passively embrace change, Because there's basically no business logic in the view. Now we can foresee that humans will be victory in isolating views and models, and people will try to make controller/presenter/viewmodel more and more bloated, and what I want to say is to ask them to be in the area of psychological shadow when they know the truth. We tried to get each module to work together, the results of the dirty work to Controller/presenter/viewmodel, I want to say that this thing is really beautiful.

?? History is always so similar, human beings on the road of death creeping forward, continue to carry forward the fine tradition of renaming, this time is presenter was renamed ViewModel, in naming this matter, I think programmers are some kind of obsessive-compulsive factors in the inside, So when you find a thing with a new name appearing in your field of view, usually it will have two different endings, first, old wine for new bottles, we are not selling wine is feelings, second, see today's you how I repeat yesterday's story, I this old ticket can also board your passenger ship. Fortunately, MVVM has changed slightly relative to MVP, an important feature is the two-way binding, the view changes will automatically be reflected in the ViewModel, and obviously ViewModel is a model for view, it can accommodate more common model, So in a sense, ViewModel still appears as a bridge between view and model, an abstraction of view, with two layers of meaning, namely data (property) and Behavior (Command), once you understand this, ViewModel is nothing more than a special and ordinary class, especially because it needs to implement the INotifyPropertyChanged interface, because it inherits the basic idea of object-oriented programming (OOP).

More like the MVVM of MVC.

?? So far, we've basically understood the links and differences between MVC, MVP, and MVVM, but is that really the best result? Let's start by thinking about the question of what code should be written in the controller. For example, when we layered the project, what should be the controller responsible for what tasks? We can have the controller handle a separate route, we can also let the controller participate in the view logic, even when we write model, we can have two different choices, first, write a simple data aggregation entity, the specific logic is given to the controller to handle, We call this a model of anemia; second, write a data aggregation entity that holds the behavior, and the controller calls these methods in the business logic, which we call the congestion model. So, the place where we tangle, in fact, is to choose to let the controller more "heavy" or let the model more "heavy", I have been exposed to about 1 years of Android development, I think the Android project is a relatively consistent with the MVC architecture design, but we will inevitably find that The code in the activity as a controller is very bloated, because we need to be associated with views and models here, so by synthesizing the existing concepts of software architecture, we find that models and views are relatively reusable, but as a controller/presenter of both. /viewmodel is very bloated and difficult to reuse, so I wonder if we are actually using MVVM.

?? I don't know what the right way to use the MVVM schema is, because this is the first time I've come into contact with a new concept, as I've seen in a web development book I saw in the school library many years ago: when we don't understand MVC, We take it for granted that the project is divided into model, View, and Controller through a folder, which seems to be MVC. But is that really the case? In my current company project, I think it's more like using two-way binding MVC, because you can often see in ViewModel, a property of the get accessor of a variety of if-else tortured "dirty" code, And in ViewModel I basically do not see the model figure, and because the use of the concept of binding severely weakened ViewModel as the basic properties of the class, so it has no constructors, no initialization, we can see in the get accessor a variety of hard-coded, Because the requirements on the view are constantly changing, so when the whole project is over, I am very reluctant to look at the ViewModel part of the code, because the project requires to avoid writing Code-behind code, So a lot of events are replaced by command and Uieventtocommand, so that ViewModel becomes more "heavy". Originally we want to let these three have their own duties, the result is now dirty work tired all become viewmodel a person. Although two-way binding can avoid to write a large number of assignment statements, but I know viewmodel deep Heart will say: Baby Heart bitter.

?? If WPF is the biggest contributor to the technology world, I think this contribution is not two-way binding, but rather it realizes design and programming separation in the real sense, we must admit that design and programming are a creative activity, the former tend to perceptual, the latter tend to ideal, in the absence of the separation between the two, Programmers need to spend a lot of time to restore the designer's design, but for programmers, a program has no interface design in some cases is completely unimportant, in the absence of interface design, we can test the reliability of the code through unit testing, On the contrary, it is not easy for us to do this after we have the interface design, so you ask me what WPF's biggest contribution to the technology community is, and I will answer that it frees the programmer to make rational thinking more suitable for rational thinking. I don't really like declarative programming, which is the markup language that inherits from XML in WPF, because Visual Studio doesn't provide debugging support for XAML, so when you find that the view shows problems, It's hard to know if the foreground view binding is wrong or if the background ViewModel error occurs, as long as you enter a content program that conforms to the XML specification, it compiles through rather than throws an exception, because it is reflected so that performance issues are widely criticized, Second, the ViewModel notifies the foreground that the property changes need to use OnPropertyChanged, the method needs to pass in a string type value, usually refers to the name of the property, but if you define a property of a string type, when you pass this property here, Because it is a string type, it does not cause compilation errors, but I think this thing is still a bit of a pit.

Delegates and commands

?? Well, now I'd like to talk about commands and delegates in WPF, actually, before I planned to write this article, I was very curious, but when I discovered the substance of this thing, I suddenly felt that it would be particularly boring to spend so much space explaining such a concept. Our project was using a framework called MVVM Light, and of course we didn't use all of its features, and the company's predecessors were very wretched to pick up some source code from this open source project, and I don't want to mention the details about the framework itself, Because I think understanding the substance of the problem is more important than learning a framework. First, WPF provides a command dependency property for each control, because any class that implements the ICommand interface can be associated with the foreground by binding, and here we compare the differences between commands and routed events to find out, The routed event must be written in the Code-behind code, and the command can be written in ViewModel, so the command is more freely and flexibly intuitive. Let's take a simple example to analyze the relationship between the two.

?? We know that using the command requires implementing the ICommand interface, so it is relatively easy to implement, and we continue to use the name Relaycommand in MVVM light:

 Public classrelaycommand:icommand{Private ReadOnlyaction<Object> M_execute;Private ReadOnlypredicate<Object> M_canexecute; Public Relaycommand(action<Object> Execute) { This. M_execute = Execute; } Public Relaycommand(action<Object> Execute, predicate<Object> CanExecute) { This. M_execute = Execute; This. M_canexecute = CanExecute; } Public BOOL CanExecute(ObjectParameter) {if(M_canexecute = =NULL)return true;returnM_canexecute (parameter); } Public EventEventHandler canexecutechanged {add {commandmanager.requerysuggested + =value; } remove {commandmanager.requerysuggested-=value; }    } Public void Execute(ObjectParameter) { This. M_execute (parameter); }}

We can see there are two important methods here, execute and CanExecute, which is a void type method, and the latter is a bool type method. When we need to determine whether a control should perform a process, canexecute this method can help us to complete the judgment, and the Execute method is obviously the way to execute a process, you can notice that by delegating us to give the caller more freedom and flexibility to pass in a method, This is one of the things I like about this design because one of my colleagues doesn't understand the normal routed events.

?? This is the Canexecutechanged event, similar to the PropertyChanged member in the INotifyPropertyChanged interface, which notifies the view when the CanExecute is changed. My understanding here is that CanExecute itself has support for whether a process should be implemented, but unfortunately, in the projects I participate in, people prefer to declare a large number of Boolean variables to handle the relevant logic here, so whether it's for property or command, In the ViewModel is a code implementation that looks very ugly.

?? Well, this is a very enjoyable journey for us now, because the process of binding commands and defining commands is very simple after you have finished defining the Relaycommand. In addition, WPF provides a RoutedCommand class that implements the ICommand interface, and I suspect that the Eventtocommand in MVVM light is the way to implement routed event-to-command conversions. Because only RoutedCommand has the ability to access UI events, here we only ask questions, further thinking and verifying that we can stay until later. Let's take a look at how to declare and bind a command:

public RelayCommand ClickCommand{    get    {        returnnew RelayCommand((arg)=>        {            MessageBox.Show("Click");        });    }}

Obviously this clickcommand will appear as a property in ViewModel, I have chosen one of my favorite methods, perhaps this looks very low-end. However, in the process of debugging the interface, it is more direct and intuitive than the breakpoint debugging. When such a read-only attribute is present in our ViewModel, it seems to be the most straightforward scheme to define its return value directly in the get accessor, but the problem is that the get accessor should be very "light" because of the infiltration of a lot of business logic, and now it can't even retain its purity? It makes me very depressed.

<window x:class="Wpflearning.window1"xmlns="http// Schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns:x=" http://schemas.microsoft.com/ Winfx/2006/xaml "Title=" window " Height=" Width= " ">                            <Grid>        <button Content="button" horizontalalignment="Center"  VerticalAlignment="Center" Command="{Binding clickcommand}"/>                   </Grid></Window>

Now you can see that the delegate and the command are very well combined, and when you find it all so wonderful, the return to nature may be our favorite thing, just like you and me, in this world, we decorate each other with the beautiful scenery of their lives, persistent and brave, warm and bright, those days of the cycle, Always hear the sound of dream blossom.

Summary

?? In this article we discuss the causes and consequences of the evolution of the MVC, MVP, and MVVM architectures, so we know that a typical design goal in software design is to separate the view from the model, but we also find that when we design the software with this goal, we seldom change the view, Although in theory all business logic is in ViewModel, the view and model should be replaceable, but you tell me, who will make a different interface for the same software? Can we expect a static factory to return different views for different platforms, and then theoretically, as long as the correct controller can be adapted to the different platform of the software "adaptive", but the development of software development so far, the most likely to provide a complete cross-platform solution of the Web technology is currently unable to meet this demand, So should we doubt the correctness of this design? Similarly, the "profile" genre, represented by the Java three-frame SSH framework, believes that the information about the database should be written in the configuration file, which will satisfy our need to switch to different database products at any time, but can you tell me how many such scenarios are used? So, the design of the technology itself is not a problem, we need to think about whether it should be framed and architecture, in the end, we are to design a better software products, as a goal, in fact, the framework and architecture should be derived from a philosophical sense of thought, we want each line of code is full of wisdom light, It is proud but not lonely, because there is always someone who understands it and understands it.

An analysis of the relationship between commands and delegates in the MVVM mode in WPF

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.