C# 使用UserControls扩展:如何将可组合部分返回到初始状态?
我有一个用UserControls扩展的主机WinForm应用程序。组合和实例化在初始启动时非常有效。当我关闭用户控件时,我想假设它应该被释放。但是,当我想再次显示用户控件时,这会导致一个问题 我想做的是,在我确保对象已释放任何资源后,将用户控件返回到其原始状态 以下是一个扩展用户控件:C# 使用UserControls扩展:如何将可组合部分返回到初始状态?,c#,winforms,.net-4.0,user-controls,mef,C#,Winforms,.net 4.0,User Controls,Mef,我有一个用UserControls扩展的主机WinForm应用程序。组合和实例化在初始启动时非常有效。当我关闭用户控件时,我想假设它应该被释放。但是,当我想再次显示用户控件时,这会导致一个问题 我想做的是,在我确保对象已释放任何资源后,将用户控件返回到其原始状态 以下是一个扩展用户控件: [ExportMetadata ( "ModuleName", "ContactManager" )] [Export ( typeof ( IUserModule ) )] partial class ucx
[ExportMetadata ( "ModuleName", "ContactManager" )]
[Export ( typeof ( IUserModule ) )]
partial class ucxContactManager : IUserModule
{
#region Fields
// Fields
readonly string moduleName = "ContactManager";
readonly string moduleDescription = "Contact Manager Extension Module";
// called from ucxContactManager constructor
void InitializeUserModule ( )
{
Closing += ( o, e ) => Dispose ( );
uxCloseContactForm.Click += ( o, e ) => Closing ( this, null );
}
// IUserModule Members
public event EventHandler<EventArgs> Closing = delegate { };
}
[ExportMetadata(“ModuleName”、“ContactManager”)]
[导出(类型(IUserModule))]
分部类ucxContactManager:IUserModule
{
#区域字段
//田地
只读字符串moduleName=“ContactManager”;
只读字符串moduleDescription=“联系人经理扩展模块”;
//从ucxContactManager构造函数调用
void InitializeUserModule()
{
关闭+=(o,e)=>Dispose();
uxCloseContactForm。单击+=(o,e)=>关闭(此为空);
}
//IUSER模块成员
public event EventHandler Closing=委托{};
}
CompositionController完成所有发现和合成工作,提供请求特定模块的方法:
// Lazily import all IUserModule interfaces
[ImportMany ( typeof ( IUserModule ), AllowRecomposition = true )]
public IEnumerable<Lazy<IUserModule, IQueryMetadata>> Modules { get; set; }
public bool TryGetModule ( string ModuleName, out IUserModule Module )
{
var module = Modules.Where ( m => m.Metadata.ModuleName == ModuleName )
.Select ( m => m )
.FirstOrDefault ( );
if (module != null)
{ Module = module.Value; }
else
{ Module = null; }
return Module != null;
}
//延迟导入所有IUserModule接口
[导入数量(类型(IUserModule),AllowRecomposition=true)]
公共IEnumerable模块{get;set;}
public bool TryGetModule(字符串模块名,输出IUserModule模块)
{
var module=Modules.Where(m=>m.Metadata.ModuleName==ModuleName)
.选择(m=>m)
.FirstOrDefault();
如果(模块!=null)
{Module=Module.Value;}
其他的
{Module=null;}
返回模块!=null;
}
现在,当我们找到模块时,分配module.Value
会导致初始化用户控件-调用构造函数
当用户控件关闭并释放时,如何将模块返回到此初始状态?我认为您的问题在于您正在将
module
设置为module.Value
,因此您正在通过Lazy
实例实例化实际的IUserModule
。如果以后才需要它,为什么不将Module
设置为Lazy
实例,然后在需要时创建它的实例呢
你可能需要考虑的另一件事是部分的寿命。除非您正在重新组合模块
集合,否则您将只有一个IUserModule
实例,因为它是通过Lazy
实例创建和实例化的。您可能需要考虑的是使用<代码> ExpPuttoStudio每次轮换一个新的实例。
ExportFactory
不是.NET 4.0的一部分(它制作成Silverlight,但不是完整的.NET 4.0 BCL。Glenn Block发布了一个用于.NET 4的版本,您可以获得。我认为您的问题是您正在将模块设置为模块.Value
,因此您正在通过惰性实例实例化实际的IUserModule
直到稍后,为什么不将模块
设置为惰性
实例,然后在需要时创建它的实例呢
另一件您可能需要考虑的部分是生命周期。除非您正在重新编写<代码>模块<代码>集合,否则只有一个实例< <代码> IUserModule >代码>,因为它是通过<代码>懒惰< /代码>实例创建和实例化的。而是每次固定一个新实例
ExportFactory
不是.NET 4.0的一部分(它是Silverlight的一部分,但不是完整的.NET 4.0 BCL。Glenn Block发布了一个适用于.NET 4的版本,您可以获得该版本。I仅在单击激活器(菜单项)后分配module.Value
。IUserModule是一个用户控件(此处假设)。我将查看ExportFactory…谢谢。我正在重新设计,因此这不是问题。主机不会直接实例化UserControl。相反,我将把UserControl封装在一个超类中,该超类将执行IUserModule实现。我只为激活器(菜单项)分配模块.Value
已单击。IUserModule是一个用户控件(此处假设)。我将查看ExportFactory…我正在重新设计,因此这不是问题。主机不会直接实例化UserControl。相反,我将在一个超类中封装UserControl,该超类将执行IUserModule实现。