我已经创建了一个UserControl,它使用[Import]
属性导入了多个部件。
public class MyUserControl : UserControl, IPartImportsSatisfiedNotification
{
[Import]
public IService Service { get; set; }
public MyUserControl()
{
}
public void OnImportsSatisfied()
{
// Do something with Service.
}
}
此UserControl是从XAML实例化的,因此无法满足其导入要求,并且没有调用OnImportsSatisfied
。
<local:MyUserControl />
我的问题是,在XAML中创建类时如何满足类的导入要求。
要在XAML中实例化为对象元素,自定义类必须满足以下要求:自定义类必须是公共的,并且必须公开默认的(无参数)公共构造函数。 (请参阅以下部分的注释关于结构。)自定义类不得为嵌套类。全名路径中的多余“点”使类名空间划分变得模棱两可,并且干扰其他XAML功能,例如附加属性。如果对象可以实例化为对象元素,则创建的对象可以填写采用对象作为其基础类型。
您仍然可以提供对象值对于不满足这些条件的类型,如果您启用一个值转换器。有关更多信息,请参见类型转换器和标记。XAML的扩展。
从那里,您有两个选择:1)使用TypeConverter:使用类型转换器将允许您在没有无参数构造函数的情况下实例化对象,但是必须提供一个TypeConverter来进行实例化。
现在,我不再需要使用它,我无法进一步帮助您。2)使用ServiceLocator检索IService:
public class MyUserControl : UserControl
{
public IService Service { get; set; }
public MyUserControl()
{
Service = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IService>();
// You can do something with Service here already.
}
}
我知道这是您班级设计的改变,但希望您可以应付。
希望这会有所帮助,宝贝
我发现调用CompositionContainer.ComposeParts(myUserControl)
是可行的。我将此称为控件的构造函数。您需要以某种方式获得对CompositionContainer的引用:
public MyUserControl()
{
compositionContainer.ComposeParts(this);
}
其他解决方案:
这可能是不必要的,但这是另一种方式。这更加令人费解,但是它确实允许您在XAML中“Import
”用户控件。为了使您的导入满意,需要导出
MyUserControl
,然后由MEF实例化。我的解决方案是在包含“ Locator”对象的类中具有静态字段。此Locator对象负责导入和返回导出的对象。然后,我可以像这样在XAML中引用此静态字段:
<ContentControl Content="{Binding MyUserControl, Source={x:Static v:SomeClass.Locator}}">
SomeClass
具有称为Locator
的静态属性,该属性在应用程序生命周期的早期分配。然后,定位器可能具有MyUserControl
属性,该属性获得Import
ed。
(免责声明:下面的链接是指向我自己的框架和解决方案的,尽管是粗略的,如果使用的话,应谨慎使用。)
[提供上述示例,我将解释如何在框架中实现它:
在我的情况下,SomeClass
是System.Windows.Application
的子类,它替换了App.xaml
,并且在ViewLocator
上分配了OnStartup
,如here所示。ViewLocator class是导入具有自定义System.Dynamic.DynamicObject
属性的视图的ViewExport
。使用ViewExport
属性标识视图。
ViewExportAttribute.Alias
是正在导出视图并为其分配别名的示例。
最后,视图的MEF实例化实例可以在XAML中如下使用: