Deep Dive is a good word. Hou Daxia's "deep dive into MFC" is still reading a book titled "deep dive. In-depth understanding Program The principle behind implementation is the true thorough understanding of a knowledge. Although I have been studying WPF recently, I feel that there is no substantial learning achievement. For example, some lower-level principles with more details are always confused, when studying the relationship between the WPF parent window and the Child Window, I think we should have a deeper understanding of the implementation technology behind the WPF window so that we can use it in a simple way.
First, you can directly generate a WPF window through the console to understand the essence of the WPF window from the lower layer. Create a C # console program and add reference: windowsbase, presentationcore, presentationframework, and system. axml. In this way, we can generate a WPF application through the console, and then introduce using system. windows; and using system. Windows. Controls in the CS file;
Using system; using system. collections. generic; using system. LINQ; using system. text; using system. windows; using system. windows. controls; namespace consoleforwpf {class program {[stathread] Static void main (string [] ARGs) {window = new window (); window. title = "leleforwpf application"; window. show ();}}}
AboveCodeAs shown in, run the program and you can see that the two windows are flashing. Note that we need to declare [stathread] before the main method,Because the com thread model of the application is a single-threaded Unit [sta],If you do not declare this, you can see that an exception occurs. To let the window stay, we declare an app object.
Using system; using system. collections. generic; using system. LINQ; using system. text; using system. windows; using system. windows. controls; namespace consoleforwpf {class program {[stathread] Static void main (string [] ARGs) {window = new window (); window. title = "leleforwpf application"; window. show (); Application APP = new application (); app. run (window );}}}
At this time, we can see that the WPF program we need is generated through the console. Next, let's take a deeper look at the application class and the execution process of the app. Run function.
First, let's take a look at the application class in WPF. application is an address space. In WPF, an application is an application instance in the system. Windows namespace. An application can only correspond to one application instance, and the life cycle of the application is from the start of the application to the end of the application.
There are two ways to create an application class. One is explicit and the other is implicit. The one on the console is explicit. When creating an application object, will applyStatic Property currentAssign the newly created object, so app. Run () can also be replaced with application. Current. Run (). We have already come into contact with implicit creation, that is, when we create a WPF project through vs, we can see the app. XAML. Open the background file of APP. XAML and we can see it,Define a class for inheritance and Application in the codeIn the class, rewrite the onstartup event corresponding to the onstartup event when the application is started (when the run method is called), and instantiate the main form in the method. in fact, the main function is automatically created in WPF, and the app corresponding to the application specified in the project file is used. XAML: instantiate the application class and call the run method. in addition to specifying the instantiated main form in the onstartup time corresponding minute method, you can also. in the XAML file, specify the main window that is instantiated and displayed when the program is running.
Then let's take a look at the app. Run function. The function prototype is:
Public int run () {eventtrace. normaltraceevent (eventtraceguidid. apprunguid, 0); return this. Run (null );}
In the above code, we can see eventtrace. normaltraceevent. Here information routing is started (detailed description of routing, and again I strongly think msdn is a good thing ). Let's look at the following code:
[Securitycritical] public int run (window) {base. verifyaccess (); If (inbrowserhostedapp () {Throw new invalidoperationexception (Sr. get ("cannotcallrunfrombrowserhostedapp");} return this. runinternal (window);} internal static bool inbrowserhostedapp () {return (browserinterophelper. isbrowserhosted &&! (Current is xapplauncherapp ));}
Verifyaccess checks whether the thread accessing this WPF is the main thread. If not, an exception is thrown. The inbrowserhostedapp function is used to determine whether the current program is a browser application rather than a XAML application. If a browser application is not a XAML application, an exception is thrown.
Here, we only need to check the running environment. The more important code is in the runinternal function, which constructs a message loop for the application. When you run the above program, two windows will pop up, one is the WPF window and the other is the console window. This is because the compiler adds the program itself. We can rewrite the code so that the program only pops up a WPF window.
At this time, I think, if two window instances are defined in the main function, which window instance will app. Run execute? In fact, when you do this, both instances will be executed, and, as long as you close one of the windows, another window will be closed. In this case, we need to understand the application class closing mode. There are three application close modes: onmainwindowclose, onlastwindowclose, and onexplictshutdow. You can see through msdn that the three attributes are as follows:
The default shutdownmodel Enumeration type is onlastwindowclose. Therefore, when we define two windows, the entire application will be closed as long as one of them is closed or one of them responds to the shutdown function, when we set the app. shutdownmode = shutdownmode. onmainwindowclose; or onexplicitshutdown, if one of the windows is closed, the other is not affected.
The above is a deep analysis of the creation and exit of an application. Next, we will analyze the response events of the WPF window. Once initialized, the window responds to events, which are usually user input, click, and so on. The application delegates these events in the uielement, while windows inherits the events. The following code adds a response event for the newly created window:
[stathread] Static void main (string [] ARGs) {window window1 = new window (); window1.title = "leleforwpf Application 1"; window1.mousedown + = new mousebuttoneventhandler (win_mousedown); window1.show (); Application APP = new application (); app. shutdownmode = shutdownmode. onmainwindowclose; app. run ();} static void win_mousedown (Object sender, Mousebuttoneventargs e) {window win = sender as window; If (win! = NULL) {MessageBox. Show ("mousebuttondown", win. Title) ;}
WE Use Window win = sender as window to obtain the window instance that sends this event. In fact, in addition to this method, we can also use MessageBox. show ("mousebuttondown", application. current. mainwindow. title);, that is, application. current. mainwindow to obtain the window instance of the current running program.
for the Application class, once the application's run method is called, an onstartup event will be issued. Once the run method returns, an onexit event will be issued. if the program needs to handle these events, you can add the corresponding response to it, or you can inherit the application directly, and then rewrite these functions. The following Code indicates that the onstartup function is important, generate the WPF window directly in the function.
Protected override void onstartup (startupeventargs e) {base. onstartup (E); // defines the code to be called during initialization. // if multiple windows are initialized here, the system will default the first window that calls the show method when the main window is window = new window (); window. title = "leleforwpf application"; window. show ();} /// <summary> /// when the operating system is canceled or disabled, the application is triggered to call this event. // by default, the application is exited directly //// /// </Summary> //// <Param name = "E"> </param> protected override void onsessionending (sessionendingcancel Eventargs e) {base. onsessionending (E); messageboxresult MB = MessageBox. Show ("do you want to save your data? ", Mainwindow. Title, messageboxbutton. yesno, messageboximage. Question); E. Cancel = (MB = messageboxresult. Yes );}
As we have demonstrated earlier, we can get multiple window instances by defining multiple windows. In this case, we can pay attention to the Windows attribute, windows properties are a collection of all forms that contain all form resources in the application. The following code defines multiple windows to access each window in sequence:
Void wint_mousedown (Object sender, mousebuttoneventargs e) {foreach (window win in Windows) {MessageBox. show (string. format ("sender window is {0}, main window is {1}", win. title, mainwindow. title ));}}
The discussion of the WPF window has come to an end, and new learning achievements will be recorded.