C# WinForm運行一個窗體實例

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

class CGlobal{static isShow=false;}
在dialogForm.Show();之前判斷一下。
if(CGlobal.isShow==false)
{dialogForm.Show();}
窗體顯示後
Form_Load(){CGlobal.isShow==true;}
方法不優雅,但是容易理解。

參考一: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的,目的也是這樣,禁止多次生成實例。新手感想,有問題請幫忙指出

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