A simple example is that you're using many applications, such as when you're using Microsoft Word, and no matter how many documents you open, the system can only load one Winword.exe instance at a time. When you open a new document, the document appears in a new window, but there is always only one application that controls all document windows, such as the ability to provide a document that tiles adjacent windows in all of the current documents.
For an application that creates a single instance, WPF itself does not provide its own workaround, but it can be done in a flexible way-the idea is to check whether another instance is running when the Applicationstartup event is triggered. The method is done by using a global mutex pair image (a mutex is a synchronization method provided in the operating system for interprocess communication). Although simple, it has limited functionality, such as the inability of new instances to communicate with existing instances. Especially for a document-based program, this is really a problem, if the new instance needs to tell an already existing instance to open a new document, or if the document is passed through a command-line argument, what method should be used to solve the problem??
One of the easiest ways for the WPF team to recommend us is to use the built-in support provided by Windows Forms, which was originally used for VisualBasic applications, using the Special new of Window forms and VisualBasic to develop C # based WPF program, there is a new legacy application that essentially serves as a wrapper for WPF applications. The process is: When you start a program, legacy applications are created, legacy applications then create WPF applications, legacy applications handle instance management, and WPF applications handle true applications.
Here we demonstrate the steps to create a single-instance application using an example:
One. Create a WPF Form project and add a Microsoft.VisualBasic.dll reference.
Two. First create a Document.xaml, and Documentlist.xaml window file that uses the defined class DocumentReference to represent a reference to the document.
DocumentReference:
1 Public classDocumentReference2 {3 Privatedocument document;4 PublicDocument Document5 {6 Get{returndocument;}7 Set{document =value;}8 }9 Ten Private stringname; One Public stringName A { - Get{returnname;} - Set{name =value;} the } - - PublicDocumentReference (document document,stringname) - { +Document =document; -Name =name; + } A}
View Code
Document.loadfile () reads the contents of the document through the file name, and the document.onclosed () event is triggered when the document form is closed and used to remove instances from the dynamic collection.
Public Partial classDocument:window {PrivateDocumentReference Docref; PublicDocument () {InitializeComponent (); } Public voidLoadFile (documentreference docref) { This. Docref =Docref; This. Content =File.readalltext (docref.name); This. Title =Docref.name; } protected Override voidonclosed (EventArgs e) {Base. Onclosed (e); ((Wpfapp) application.current). Documents.remove (DOCREF); } }
View Code
The Documentlist form places a lstdocuments control that <listbox name= "lstdocuments" ></ListBox> to display the current document list.
1 Public Partial classDocumentlist:window2 {3 Publicdocumentlist ()4 {5 InitializeComponent ();6 7Lstdocuments.displaymemberpath ="Name";8Lstdocuments.itemssource =((Wpfapp) application.current). Documents;9 } Ten}
View Code
Three. Then create a custom WPF class WpfApp.cs, which inherits from Windows.application. In this case, the Onstartupnextinstance method of the Singleinstanceapplication class is triggered whenever a command-line argument is passed to the Singleinstanceapplication class file name, and the custom The showdocument () method loads the document form for the specified documents.
Wpfapp:
1 Public classwpfapp:application2 {3 Privateobservablecollection<documentreference> documents =4 NewObservablecollection<documentreference>();5 PublicObservablecollection<documentreference>Documents6 {7 Get{returndocuments;}8 Set{documents =value;}9 } Ten One protected Override voidOnstartup (System.Windows.StartupEventArgs e) A { - Base. Onstartup (e); - //wpfapp.current = this; the -Documentlist list =Newdocumentlist (); - This. MainWindow =list; - list. Show (); + - //Load the document that is specified as an argument. + if(E.args.length >0) showdocument (e.args[0]); A at } - - Public voidshowdocument (stringfileName) - { - Try - { inDocument doc =NewDocument (); -DocumentReference Docref =NewDocumentReference (Doc, fileName); to Doc. LoadFile (docref); +Doc. Owner = This. MainWindow; - Doc. Show (); the Doc. Activate (); * Documents.Add (docref); $ }Panax Notoginseng Catch - { theMessageBox.Show ("Could not load document."); + } A } the}
View Code
Four. Create a custom class that inherits from Windowsformsapplicationbase SingleInstanceApplication.cs This class will provide 3 important members for managing the instance.
- The issingleinstance is used to determine whether this application is a single-instance application, and the value is set to true in the constructor.
- Override Onstartup (), override the method when the program starts, and create a WPF Application object.
- overriding Onstartupnextinstance (), which fires the method when another application starts, provides the ability to access the parameters of the command line. You can call the methods of the WPF application class to create the window, but you cannot create another application object.
Singleinstanceapplication:
1 Public classSingleinstanceapplication:windowsformsapplicationbase2 {3 PrivateWpfapp App;4 Publicsingleinstanceapplication ()5 {6 This. Issingleinstance =true;7 }8 9 protected Override BOOLOnstartup (Microsoft.VisualBasic.ApplicationServices.StartupEventArgs EventArgs)Ten { One stringExtension =". Testdoc"; A stringtitle ="singleinstanceapplication"; - stringExtensiondescription ="A Test Document"; - the //return base. Onstartup (EventArgs); -APP =NewWpfapp (); - App.run (); - return false; + } - + protected Override voidonstartupnextinstance (Startupnextinstanceeventargs EventArgs) A { at //base. Onstartupnextinstance (EventArgs); - if(EventArgs.CommandLine.Count >0) -App.showdocument (eventargs.commandline[0]); - } -}
View Code
Five. Since the application needs to create the Singleinstanceapplication class before the app class, it is necessary to use the traditional main method as a startup entry.
public class Startup { [STAThread] public static void Main (string[] args) { Singleinstanceapplication wrapper = new Singleinstanceapplication (); Wrapper. Run (args); } }
Six, in order to test a singleton program, you need to use the window file name extension to associate with the program and register its file type. The results of the operation are as follows:
Create a single-instance application using WPF