Implementation and description of the wpf mvvm enterprise framework starting from 0, wpfmvvm

Source: Internet
Author: User

Implementation and description of the wpf mvvm enterprise framework starting from 0, wpfmvvm

When talking about desktop applications, our first response is how the messaging mechanism is handled. Let's talk about this windows messaging mechanism first.

 

When talking about the word "Message mechanism", we will all think of Windows Message mechanism. The system packs the keyboard and mouse behavior into a Windows Message, then, the system sends these Windows messages to a specific window. In fact, messages are sent to the Message Queue of the thread where the specified window is located, the message loop of the application continuously obtains messages from the message queue, and sends the messages to the Window Process of the specific window class for processing. In the window process, the user interaction is completed.

In fact, the underlying level of WPF is also based on the Win32 message system. How does a WPF Application interact with Win32 messages? What kind of mechanism does it have? Next, I will introduce the message mechanism through the following blog posts:

Let the application get started

When talking about WPF messages, we should first know the roles of DispactherObject and Dispatcher in the WPF system.

Most of WPF objects are derived from DispatcherObject. The derived objects have an obvious feature: the thread where the object is modified, it must be the same Thread as the Thread where the object is created. This is Microsoft's simplest understanding of Thread affinity. Who can guarantee the affinity of the thread? That's Dispacher. The Type derived from DispatcherObject inherits three important members: the Dispatcher attribute, CheckAccess (), and VerifyAccess () methods. The following two methods are used to check the affinity of the thread. According to the implementation of WPF, if you define a WPF type and a subclass of DispatcherObject, you must call the base at the beginning of the logic defined by the public member. dispatcher. verifyAccess () to verify the affinity of the thread. So what else does Dispatcher do?

First, let's take a look at the logic behind the startup of the next WPF Application:

From the call stack, we can see that the blue part starts a thread, and Visual Studio runs the current Application in the Host process. The red part is from Application. the Main function is executed, and several functions are passed to the Dispatcher. run (), and finally reach Dispather. pushFrameInpl () method. So why does an Application call Dispatcher. Run () after Run? What has it done to you? If you carefully check Application. Run () through Reflector, you will find that there are not many actually used code in it, and finally Dispatcher. Run is doing things. After an Application is started, according to the previous understanding of the Win32 message mechanism, after the Application is started, it must enter a message loop. The same applies to WPF. So where does the WPF Application enter the message loop? In fact, this is what Dispatcher. Run () does. Check the code of Dispacther. PushFrameImpl () in the last step. You will see the following code:

Obviously, the orange part is a loop. Does it look familiar? Is it similar to the message loop encountered by Win32 programming? By the way, the WPF application enters the message loop. The GetMessage method is called cyclically to get messages from the message queue of the current thread. After a msg is retrieved, it is handed over to the TranslateAndDispatchMessage method for processing in different window. In this way, any messages that need to be processed by the application are processed by different windows, and the application starts to work.

  

 

 

In the following section, I will introduce Win32 windows in WPF. These windows process messages from the system or from within the application.

 

Five windows in WPF

For Windows systems, it is a message system, and the core of the message system is the window. This is also true for WPF. So why do windows need to exist in WPF?

Previously, we often mentioned "thread". "Dispatcher", in fact, the thread where the running WPF Application is located is the so-called UI thread of WPF. call Dispatcher. run checks whether a Dispatcher object exists in the current thread. If no Dispatcher object exists, construct one. Here, a thread corresponds to one Dispatcher. Therefore, when a WPF object obtains the this. Dispatcher attribute, different objects take the same Dispatcher instance. In addition, the "message loop" and "message queue" mentioned above are all Win32 application concepts. We know that when these concepts are mentioned, they will inevitably follow Win32's "window ", "Handle", "WndProc" and other concepts are inseparable. Is there any "form", "Handle", or "WndProc" in WPF?

What I want to say is: yes, there are more than one, but they are not exposed, and you do not need to care about them outside.

Generally, when a WPF application is running, five Win32 windows are created in the background to help the WPF system process messages in the operating system and in the application. Only one of the five windows is visible. It can process input events and user interaction. The other four windows are invisible and help WPF process messages from other sources. Next, I will introduce how these five Win32 Windows Help WPF process messages. I will introduce the order in which each window is created.

 

Hide message window (Window 1 # )

Creation Time: when the Application constructor calls the DispatcherObject constructor of the base class, a Dispatcher object is created in the private constructor of the Dispatcher.

Purpose: Implement Asynchronous calls to the WPF thread model.

When talking about asynchronous calls, I believe many people are familiar with it. In WinForm, we usually divide this operation into many steps to make some method calls that spend a lot of time without affecting the UI response, and then use BeginInvoke to call each step, in this way, the UI response will not be blocked. The essence of BeginInvoke is to send a message to the Message Queue instead of calling it directly. At the same time, the UI behavior (MouseMove) causes the system to update the UI in the message queue by using the PostMessage. However, it takes a short time for each other to update the UI, the interface will not be blocked if two messages are processed at the same time. WPF also faces such a problem. How does it solve it? Here Window 1 # plays a vital role. The following figure shows what Window 1 is doing?

WPF is also implemented through BeginInvoke, while Wpf's BeginInvoke is exposed on the Dispatcher because the entire message system is coordinated by Dispatcher. The figure above shows the process that Dispatcher experienced after calling BeginInvoke, and when Foo () was actually executed.

Step 1The call Delegate and priority are encapsulated into a DispatcherOperation and put into the priority Queue maintained by the Dispatcher. This Queue is sorted by DispatcherPriority, And the DispatcherOperation with a higher priority is always processed first. For more information about priority, see MSDN's explanation of the WPF thread model.

Step 2To Post a Message named MsgProcessQueue to the Message Queue of the current thread. This message is defined by WPF. For details, refer to the static constructor of Dispatcher.

_ MsgProcessQueue = UnsafeNativeMethods. RegisterWindowMessage ("DispatcherProcessQueue ");

Before the message is Post to the message queue, you must set MSG. Handle, which is the Handle of Window 1. Handle is used to specify the window WndProc (Window Process) in which to process the message when the message is cyclically Dispatch. All the messages caused by BeginInvoke are processed by the Window1 # window process.

Step 3To read messages cyclically.

Step 4The system obtains the Handle of the message and finds that it is the same as the Handle of Window1 #. Then, the message is distributed to the window of Window1 # for processing.

Step 5In the window, take a DispatcherOperation in the priority queue.

Step 6Run the DispatcherOperation. Invoke method. The core of the Invoke method is the Delegate passed in when the DispatcherOperation construction is called, that is, the Delegate passed in by Dispatcher. BeginInvoke. Finally, the Foo () method is executed.

Through the above six steps, a Dispatcher. BeginInvoke is processed. This process requires the continuous flow of messages, so you must join the message queue and finally handle specific window processes. The core thing is this hidden Window1 #, in WPF, he is only responsible for processing asynchronous calls. He does not care about other messages, and the remaining four windows are being processed. This Window1 # contains a shell in WPF. If you are interested, you can view the MessageOnlyHwndWrapper type.

 

 

 

Process application activation and system close windows (Window 2 # )

Creation Time: after Application. Run is called, Run it in the Application. EnsureHwndSource () method.

Purpose: distribute Application Activated, Deactivated, and SessionEnding events.

For the sake of security, WPF does not allow the UI window to process the application activation, anti-activation, and the corresponding message when the operating system is closed. Instead, it creates a hidden window internally, it is used to receive Windows messages WM_ACTIVATEAPP and WM_QUERYENDSESSION. After obtaining the two messages from the thread message queue, three events, Application. Activated, Application. Deactivated, and Application. SessionEnding, are triggered for WPF.

For more details, see EnsureHwndSource () and AppFilterMessage () of the Application type.

The preceding process can be described as follows:

 

 

 

System Resource Change Notification Window(Window 4 #)

Creation Time: After the MainWindow Xaml of the Application is deserialized into an object, you need to confirm the ThemeStyle of the Window.

Purpose: update the performance of WPF when the Theme of the operating system changes and the resources associated with the system, such as SystemColors, SystemFonts, power supply, and display.

After the initialization of the MainWindow that appears in the application is complete, WPF creates a hidden window to process the updated messages from system-related resources, such as WM_ThemeChanged, WM_SystemColorChanged, wm_display, WM_PowerBroadcast, and so on. Similar to the original intention of Window2 #, for the sake of security, these messages are not processed through visible UI windows, but the hidden Window4 # window is created for the content to process these messages, ensure that the UI window can be securely updated due to changes in the system Theme and related resources.

The preceding process can be described as follows:

 

 

 

I wanted to write the logic of this WPF message mechanism by myself. After all, I had limited qualifications. I saw a great man on the Internet write more comprehensively and carefully. Then I quoted it and made some changes, this makes it easier for you to understand. Many things in the future will be handled based on such a windows message mechanism, especially message notifications at the View and Viewmodel layers, there are also some thread security issues.

 


Reference: http://www.cnblogs.com/therock/articles/2140459.html

Related Article

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.