商業(yè)源碼熱門下載www.html.org.cn
很多情況下,我們需要一個singleton窗體,比如,任務管理器就可以是windows應用系統(tǒng)中的一個singleton,于是我們這樣做:在窗體類的實現(xiàn)中添加一個靜態(tài)指向單件的成員,提供一個靜態(tài)的createinstance方法,當?shù)谝淮握{用此方法時創(chuàng)建單件。另外還要處理closing事件,以使點擊窗體右上角的“×”時,隱藏窗體。每次需要實現(xiàn)一個單件窗體時都要這么做,于是我決定寫一個基類isingletondisplayer,一個窗體不用作任何改變,只需要將原來的基類form改為isingletondisplayer就變成一個singleton窗體,這就很方便了。先給出在vs2003中的實現(xiàn)。public class isingletondisplayer : form //從form繼承
{
private static isingletondisplayer singleton = null ;
private static bool toclean = false ;
protected isingletondisplayer()
{
this.closing += new system.componentmodel.canceleventhandler(isingletondisplayer_closing);
}
#region static for singleton
#region getsingleton
public static isingletondisplayer getsingleton()
{
if(isingletondisplayer.singleton != null)
{
isingletondisplayer.singleton.visible = true ;
}
return isingletondisplayer.singleton ;
}
#endregion
#region recreatesingleton
//formonui存在是因為窗體只能在主線程(ui線程)中創(chuàng)建。
public static void recreatesingleton(type targettype ,object[] args , form formonui)
{
type suptype = typeof(isingletondisplayer) ;
if(! suptype.isassignablefrom(targettype))
{
throw new exception("target type is not derived from isingletondisplayer !") ;
}
if(formonui.invokerequired)
{
object[] paras = {targettype ,args ,formonui} ;
formonui.invoke(new cbackcreateform(isingletondisplayer.recreatesingleton) ,paras) ;
}
else
{
try
{
isingletondisplayer.toclean = false ;
isingletondisplayer.singleton = (isingletondisplayer)activator.createinstance(targettype ,args) ;
isingletondisplayer.singleton.visible = false ;
}
catch(exception ee)
{
throw ee ;
}
}
}
#endregion
#region destroysingleton
public static void destroysingleton()
{
isingletondisplayer.toclean = true ;
if(isingletondisplayer.singleton != null)
{
isingletondisplayer.singleton.close() ;
isingletondisplayer.singleton = null ;
}
}
#endregion
#endregion
#region isingletondisplayer_closing
private void isingletondisplayer_closing(object sender, system.componentmodel.canceleventargs e)
{
if(! isingletondisplayer.toclean)
{
this.visible = false ;
e.cancel = true ;
return ;
}
}
#endregion
}
internal delegate void cbackcreateform(type targettype ,object[] args , form formonui) ;
* 使用方法:
* 如果一個displayer需要以singleton模式呈現(xiàn),那么可以先以常規(guī)的方式設計displayer,設計過程中不需要涉及任何與單件
* 相關的東西。設計完后,只要將displayer的基類由form改為isingletondisplayer即可。接下來即可以單件的模式使用displayer了。
*
* 如:
* public class appserversinfoform2 : isingletondisplayer{}
* object[] args = {obj} ;
* isingletondisplayer.recreatesingleton(typeof(appserversinfoform2) ,args ,formonui) ;
上面的實現(xiàn)很容易理解,但是上面的實現(xiàn)有一個弊病,因為所有的單件窗體都要公用一個靜態(tài)的isingletondisplayer singleton 成員,所以一個應用程序中只能有一個單件繼承自isingletondisplayer。/ 在vs2005中可以使用泛型突破此限制。
下面在看看在vs2005中的實現(xiàn)。
public class isingletondisplayer<t> : form
{
private static isingletondisplayer<t> singleton = null ;
private static bool toclean = false ;
protected isingletondisplayer()
{
this.closing += new system.componentmodel.canceleventhandler(isingletondisplayer_closing);
}
public static isingletondisplayer<t> getsingleton()
{
if(isingletondisplayer<t>.singleton != null)
{
isingletondisplayer<t>.singleton.visible = true ;
}
return isingletondisplayer<t>.singleton ;
}
public static void recreatesingleton(type targettype ,object[] args , form formonui)
{
type suptype = typeof(isingletondisplayer) ;
if(! suptype.isassignablefrom(targettype))
{
throw new exception("target type is not derived from isingletondisplayer<t> !") ;
}
if(formonui.invokerequired)
{
object[] paras = {targettype ,args ,formonui} ;
formonui.invoke(new cbackcreateform(isingletondisplayer<t>.recreatesingleton) ,paras) ;
}
else
{
try
{
isingletondisplayer<t>.toclean = false ;
isingletondisplayer<t>.singleton = (isingletondisplayer<t>)activator.createinstance(targettype ,args) ;
isingletondisplayer<t>.singleton.visible = false ;
}
catch(exception ee)
{
throw ee ;
}
}
}
public static void destroysingleton()
{
isingletondisplayer<t>.toclean = true ;
if(isingletondisplayer<t>.singleton != null)
{
isingletondisplayer<t>.singleton.close() ;
isingletondisplayer<t>.singleton = null ;
}
}
private void isingletondisplayer_closing(object sender, system.componentmodel.canceleventargs e)
{
if(! isingletondisplayer<t>.toclean)
{
this.visible = false ;
e.cancel = true ;
return ;
}
}
}
internal delegate void cbackcreateform(type targettype ,object[] args , form formonui) ;
如:
public class appserversinfoform2 : isingletondisplayer<appserversinfoform2>{}
object[] args = {obj} ;
isingletondisplayer<appserversinfoform2>.recreatesingleton(typeof(appserversinfoform2) ,args ,this) ;
這樣每個單件都有自己的靜態(tài)實例,就不會相互干擾了。
如果你有更好的實現(xiàn)方法,歡迎和我討論
新聞熱點
疑難解答