WPF程序如何只允許打開一個窗口,當窗口存在時,激活窗口。
單例模式微軟社區有發表這個文章,http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/
步驟:
1、項目中新增SingleInstance.cs文件
2、添加引用 System.Runtime.Remoting
3、app.xaml.cs文件中繼承ISingleInstanceApp(源自步驟1新增的cs文件中)
如下:
public partial class App : Application, ISingleInstanceApp
4、修改項目屬性-應用程序-啟動對象,選擇為<projectname>.App的選項
5、實現app.xaml.cs的main方法,Unique 字段弄個唯一編碼即可。如下
/// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application, ISingleInstanceApp { private const string Unique = “My_Unique_Application_String”; [STAThread] public static void Main() { if (SingleInstance<App>.InitializeAsFirstInstance(Unique)) { var application = new App(); application.InitializeComponent(); application.Run(); // Allow single instance code to perform cleanup operations SingleInstance<App>.Cleanup(); } } #region ISingleInstanceApp Members public bool SignalExternalCommandLineArgs(IList<string> args) { // handle command line arguments of second instance // … return true; } #endregion }
6、修改App.xaml文件的生成操作,App.xaml-屬性-生成操作,選擇Page
到6這一步就可以實現單例了。沒有demo,自己敲一敲,復制粘貼試一下吧。~~~~
------由於自己要做窗口傳參的需求,下面是自己遇到的問題記錄一下--------
7、如果打開窗口時需要傳參,那么打開窗口的操作就需要在代碼中實現,如下:
// TODO: Make this unique!"Change this to something that uniquely identifies your program."; private const string AppId = "{22222222222222}"; [STAThread] static void Main(string[] args) { //if (SingleInstance<App>.InitializeAsFirstInstance(Unique)) //{ // var application = new App(); // application.InitializeComponent(); // application.Run(); // // Allow single instance code to perform cleanup operations // SingleInstance<App>.Cleanup(); //} //if (args.Length != 6) return; if (SingleInstance<App>.InitializeAsFirstInstance(AppId)) { var win = new MainWindow(); var vm = new MainWindowViewModel(args, win.Close); win.DataContext = vm; var application = new App(); application.InitializeComponent(); application.Run(); // Allow single instance code to perform cleanup operations SingleInstance<App>.Cleanup(); } } #region ISingleInstanceApp Members public bool SignalExternalCommandLineArgs(IList<string> args) { // handle command line arguments of second instance if (this.MainWindow.WindowState == WindowState.Minimized) { this.MainWindow.WindowState = WindowState.Normal; } this.MainWindow.Activate(); return true; } #endregion
與此同時還有一個地方需要刪除,由於已經在類中定義一個Main方法來實現對WPF應用程序的啟動。那么App.xaml里面的StartupUri刪除掉,否則會出現2個窗口或者異常
8、由於不走App.xaml,所以如果引用第三方資源的話,需要在打開的窗口里面加資源,否則資源不會加載出來。
參考原文鏈接:https://codereview.stackexchange.com/questions/20871/single-instance-wpf-application