C# WinForm只允許運行一個窗體實例

大概看了看別人的方法,都是從語法的角度巧妙實現的。
我要實現的目的是dialogForm.Show();
點擊按鈕顯示對話框窗體,如果窗體沒有關閉,再次點擊,不重複顯示。
我用了個笨方法,就是用一個靜態類,在內存中保存個數據。記錄窗體是否顯示。

class CGlobal{static isShow=false;}

在dialogForm.Show();之前判斷一下。

if(CGlobal.isShow==false)
{dialogForm.Show();}

窗體顯示後

Form_Load(){CGlobal.isShow==true;}

方法不優雅,但是容易理解,哈哈。

url:http://greatverve.cnblogs.com/archive/2011/06/28/csharp-one-form.html

參考一:C# 只允許運行一個程序實例

複製代碼

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;//使用DllImport的必須。
using System.Diagnostics;//引入Process 類

namespace 命名空間
{
    static class Program
    {

        private const int WS_SHOWNORMAL = 1;
        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Process instance = GetRunningInstance();
            if (instance == null)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new frm_Main());//在這啓動主窗體。
            }
            else
            {
                HandleRunningInstance(instance);
            }
        }
        /// <summary>
        /// 獲取當前是否具有相同進程。
        /// </summary>
        /// <returns></returns>
        public static Process GetRunningInstance()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(current.ProcessName);
            //遍歷正在有相同名字運行的例程   
            foreach (Process process in processes)
            {
                //忽略現有的例程   
                if (process.Id != current.Id)
                    //確保例程從EXE文件運行 
                    if ( System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/" , "\\") == current.MainModule.FileName )
                        return process;
            }
            return null;
        }
        /// <summary>
        /// 激活原有的進程。
        /// </summary>
        /// <param name="instance"></param>
        public static void HandleRunningInstance(Process instance)
        {
            ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
            SetForegroundWindow(instance.MainWindowHandle);
        }
    }
}

複製代碼


參考二:C#中只允許產生一個類的實例的方法

有的時候我們會碰到這樣的情況:在一個窗體中,我們點擊一個按鈕產生一個新的窗體,如果我們在代碼中不進行限制的話,再點擊一次按鈕,又會產生一個窗體,對於每個窗體當然是有一個窗體的實例和它對應,如果我想在程序中只允許生成一個類的實例該怎麼辦呢?其實實現上面不能再產生一個新的窗體還是比較簡單的實現的,可以在產生了窗體以後我們設置按鈕屬性爲不可用:Button1.Enable=false; 
但是,我在這裏想實現的是不用讓按鈕不可用,來完成程序只能產生一個類的實例的方法: 

方法一: 
如果一個類你只想一個實例對其進行操作,那麼我們可以將類中的域,屬性以及函數都定義爲static的,而且我們把構造函數定義成private的,這樣只有類名才能對類裏面的域,屬性還有方法進行訪問了,而且該類也不能在類外創建一個實例了。

 

 

public class Class2  

           private Class2(){}  
           public static Type VariableName;  
           public static Type FunctionName(){}  

這中方法不適合於WINFORM程序中的窗體類。 

方法二:  
設置一個bool型的變量來表識是否已經創建了一個實例。 

public class Class2 
    { 
        private Class2() 
        { 
        } 
        private static bool instance_flag=false; 
        public static Class2 GetInstance() 
        { 
            if(!instance_flag) 
            { 
                Class2 c2=new Class2(); 
                instance_flag=true; 
                return c2; 
            } 
            else 
            { 
                Console.WriteLine("you have already create a instance"); 
                return null; 
            } 
 
        } 
    } 

如果已經創建了一個實例,那麼instance_flag=true,這樣程序就知道已經有一個實例已經創建,將不會創建新的實例。 

方法三: 
在Class2中創建一個類的實例,該實例是static的,然後在類外面直接用這個實例進行賦值,也可通過函數來返回這個類的實例。但是這樣的話,就會在編譯的時候就會產生這個類的實例,它會浪費資源,效率也不高,可以在需要用到實例的時候才生成,代碼如下: 

    public class Class2 
    { 
        private Class2() 
        { 
        } 
        private static Class2 c2=null; 
        public static Class2 GetInstance() 
        { 
            if(c2==null) 
            { 
                c2=new Class2(); 
            } 
            return c2; 
        } 
    } 

static方法只能訪問static的域。根據以上代碼,在需要使用實例的時候,可以用類名來調用GetInstance()方法。來返回一個實例。 
以上方法不能使用構造函數,因爲都將構造函數設置成了private的,目的也是這樣,禁止多次生成實例。新手感想,有問題請幫忙指出,謝謝! 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章