Wpf MEF和插件属性更新
我是MEF的新手,开始了一个项目来测试它。我想做的是打开一个MainForm,加载基于接口的插件。这些插件需要能够在它们之间交换信息,MainForm也应该能够与所有插件通信。因此,我开始创建加载插件的MainForm。插件只是一个包含列表框的表单。主窗体上有一个按钮。我希望该按钮向插件发送一个列表(字符串),该插件将该列表(字符串)加载到列表框中。目前,当我点击MainForm按钮时,它会将列表发送到插件。但是列表没有加载到插件列表框中。为了找出问题所在,我在MainForm上添加了一个新按钮,以验证plugin属性是否包含我发送的列表(字符串)。是的,列表包含了我所有的字符串。问题应该是列表框没有刷新 接口的一部分:Wpf MEF和插件属性更新,wpf,vb.net,mef,Wpf,Vb.net,Mef,我是MEF的新手,开始了一个项目来测试它。我想做的是打开一个MainForm,加载基于接口的插件。这些插件需要能够在它们之间交换信息,MainForm也应该能够与所有插件通信。因此,我开始创建加载插件的MainForm。插件只是一个包含列表框的表单。主窗体上有一个按钮。我希望该按钮向插件发送一个列表(字符串),该插件将该列表(字符串)加载到列表框中。目前,当我点击MainForm按钮时,它会将列表发送到插件。但是列表没有加载到插件列表框中。为了找出问题所在,我在MainForm上添加了一个新按钮
Public Interface IPlugIn
Property PlugInName as string
Property Files As List(Of String)
End Interface
MainForm按钮中的代码:
Dim currentPlugIn As Contract.API.IPlugIn
currentPlugIn = PlugIns.Find(Function(x) x.PlugInName = "Test")
currentPlugIn.Files = IO.Directory.GetFiles("SomeFolder").ToList
插件中的代码:
<Export(GetType(Contract.API.IPlugIn))> _
Public Class UserControl1
Implements System.ComponentModel.INotifyPropertyChanged, Contract.API.IPlugIn
Public Property Files As System.Collections.Generic.List(Of String) Implements
Contract.API.IPlugIn.Files
Get
If IsNothing(_files) Then
_files = New List(Of String)
End If
Return _files
End Get
Set(value As System.Collections.Generic.List(Of String))
_files = value
OnPropertyChanged("Files")
End Set
End Property
Public Event PropertyChanged(sender As Object, e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(propertyName As String)
RaiseEvent PropertyChanged(Me, New
ComponentModel.PropertyChangedEventArgs(propertyName))
End Sub
_
公共类UserControl1
实现System.ComponentModel.INotifyPropertyChanged、Contract.API.IPlugIn
公共属性文件作为System.Collections.Generic.List(字符串)实现
Contract.API.IPlugIn.Files
得到
如果没有(_文件),则
_文件=新列表(字符串)
如果结束
返回\u文件
结束
Set(值为System.Collections.Generic.List(字符串))
_文件=值
OnPropertyChanged(“文件”)
端集
端属性
公共事件属性已更改(发件人作为对象,e作为
System.ComponentModel.PropertyChangedEventArgs)实现
System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(propertyName作为字符串)
RaiseEvent属性已更改(Me、New)
ComponentModel.PropertyChangedEventArgs(propertyName))
端接头
插件XAML中的代码:
<ListBox Name="lstFiles" ItemsSource="{Binding Path=Files}"/>
有什么问题吗?我在互联网上搜索了数百个例子,但没有一个能说明如何做我想做的事情。在这里发布我的问题之前,我添加了INotifyPropertyChanged,它没有解决问题。我用PRISM,Caliburn,Micro会更好吗?还是MEF会没事
谢谢你的帮助 Athari,谢谢你的评论 我确实修复了ObservaleCollection的属性,但没有修复该问题。看来我还错过了什么 这是完整的代码 接口
Namespace API
Public Interface IPlugIn
Property Files As System.Collections.ObjectModel.ObservableCollection(Of String)
ReadOnly Property PlugInUI As System.Windows.Controls.UserControl
End Interface
End Namespace
插件
Imports System.ComponentModel.Composition
<Export(GetType(Contract.API.IPlugIn))> _
Public Class UserControl1
Implements Contract.API.IPlugIn, System.ComponentModel.INotifyPropertyChanged,
System.Collections.Specialized.INotifyCollectionChanged
Private _files As System.Collections.ObjectModel.ObservableCollection(Of String)
Public Property Files As System.Collections.ObjectModel.ObservableCollection(Of String)
Implements Contract.API.IPlugIn.Files
Get
If IsNothing(_files) Then
_files = New System.Collections.ObjectModel.ObservableCollection(Of String)
End If
Return _files
End Get
Set(value As System.Collections.ObjectModel.ObservableCollection(Of String))
_files = value
OnPropertyChanged("Files")
OnCollectionChanged(New
Collections.Specialized.NotifyCollectionChangedEventArgs _
(Specialized.NotifyCollectionChangedAction.Reset))
End Set
End Property
Public ReadOnly Property PlugInUI As System.Windows.Controls.UserControl Implements
Contract.API.IPlugIn.PlugInUI
Get
Dim myUI As New UserControl1
Return myUI
End Get
End Property
Public Event PropertyChanged(sender As Object, e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New
ComponentModel.PropertyChangedEventArgs(propertyName))
End Sub
Public Event CollectionChanged(sender As Object, e As
System.Collections.Specialized.NotifyCollectionChangedEventArgs) Implements
System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged
Public Sub OnCollectionChanged(args As
System.Collections.Specialized.NotifyCollectionChangedEventArgs)
RaiseEvent CollectionChanged(Me, args)
End Sub
End Class
导入System.ComponentModel.Composition
_
公共类UserControl1
实现Contract.API.IPlugIn、System.ComponentModel.INotifyPropertyChanged、,
System.Collections.Specialized.InotifyCollections已更改
私有的_文件,如System.Collections.ObjectModel.ObservableCollection(字符串)
作为System.Collections.ObjectModel.ObservableCollection(字符串)的公共属性文件
实现Contract.API.IPlugIn.xml文件
得到
如果没有(_文件),则
_files=New System.Collections.ObjectModel.ObservableCollection(字符串)
如果结束
返回\u文件
结束
集合(值为System.Collections.ObjectModel.ObservableCollection(字符串))
_文件=值
OnPropertyChanged(“文件”)
OnCollectionChanged(新的
Collections.Specialized.NotifyCollectionChangedEventArgs_
(专用.NotifyCollectionChangedAction.Reset))
端集
端属性
公共只读属性PlugInUI作为System.Windows.Controls.UserControl实现
Contract.API.IPlugIn.PlugInUI
得到
将myUI设置为新用户控件1
返回myUI
结束
端属性
公共事件属性已更改(发件人作为对象,e作为
System.ComponentModel.PropertyChangedEventArgs)实现
System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(可选propertyName As String=Nothing)
RaiseEvent属性已更改(Me、New)
ComponentModel.PropertyChangedEventArgs(propertyName))
端接头
公共事件集合已更改(发件人作为对象,e作为
System.Collections.Specialized.NotifyCollectionChangedEventArgs)实现
System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged
公共子集合已更改(参数为
System.Collections.Specialized.NotifyCollectionChangedEventArgs)
RaiseEvent集合已更改(Me、args)
端接头
末级
插件XAML
<Grid>
<ListBox Height="248" HorizontalAlignment="Left" Margin="30,31,0,0" Name="ListBox1"
VerticalAlignment="Top" Width="241" ItemsSource="{Binding Files}">
</Grid>
主机应用程序
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Public Class HostApp
<ImportMany(GetType(Contract.API.IPlugIn))> _
Public Property PlugIns As List(Of Contract.API.IPlugIn)
Private _container As CompositionContainer
Public Sub Compose()
Dim catalog As New AggregateCatalog
catalog.Catalogs.Add(New DirectoryCatalog("pluginfolder"))
_container = New CompositionContainer(catalog)
_container.ComposeParts(Me)
End Sub
Public Sub LoadPlugIns()
Compose()
For Each item In PlugIns
Desktop.Children.Add(item.PlugInUI)
Next
End Sub
Private Sub HostApp_Loaded(sender As Object, e As System.Windows.RoutedEventArgs)
Handles Me.Loaded
LoadPlugIns()
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
Handles Button1.Click
Dim fileList As New Collections.ObjectModel.ObservableCollection(Of String)
For Each fileItem As String In IO.Directory.GetFiles("Somefolder")
fileList.Add(fileItem)
Next
PlugIns.Item(0).Files = fileList
End Sub
End Class
导入System.ComponentModel.Composition
导入System.ComponentModel.Composition.Hosting
公共类主机应用程序
_
公共属性插件列表(Contract.API.IPlugIn)
专用容器作为CompositionContainer
公共子组件()
Dim目录作为新的AggregateCatalog
catalog.Catalogs.Add(新目录目录(“pluginfolder”))
_容器=新合成容器(目录)
_容器组件(Me)
端接头
公共子加载插件()
撰写()
对于插件中的每个项目
Desktop.Children.Add(item.PlugInUI)
下一个
端接头
已加载私有子主机app_(发件人作为对象,e作为System.Windows.RoutedEventArgs)
对付我,上膛了
LoadPlugIns()
端接头
私有子按钮1\u单击(发件人作为System.Object,e作为System.Windows.RoutedEventArgs)
手柄按钮1。单击
Dim文件列表作为新集合.ObjectModel.ObservableCollection(字符串的集合)
对于IO.Directory.GetFiles(“Somefolder”)中的字符串形式的每个文件项
fileList.Add(fileItem)
下一个
PlugIns.Item(0).Files=fileList
端接头
末级
我需要在插件列表框中列出文件属性
再次感谢你的帮助 Athari,谢谢你的评论 我确实修复了ObservaleCollection的属性,但没有修复该问题。看来我还错过了什么 这是完整的代码 接口
Namespace API
Public Interface IPlugIn
Property Files As System.Collections.ObjectModel.ObservableCollection(Of String)
ReadOnly Property PlugInUI As System.Windows.Controls.UserControl
End Interface
End Namespace
插件
Imports System.ComponentModel.Composition
<Export(GetType(Contract.API.IPlugIn))> _
Public Class UserControl1
Implements Contract.API.IPlugIn, System.ComponentModel.INotifyPropertyChanged,
System.Collections.Specialized.INotifyCollectionChanged
Private _files As System.Collections.ObjectModel.ObservableCollection(Of String)
Public Property Files As System.Collections.ObjectModel.ObservableCollection(Of String)
Implements Contract.API.IPlugIn.Files
Get
If IsNothing(_files) Then
_files = New System.Collections.ObjectModel.ObservableCollection(Of String)
End If
Return _files
End Get
Set(value As System.Collections.ObjectModel.ObservableCollection(Of String))
_files = value
OnPropertyChanged("Files")
OnCollectionChanged(New
Collections.Specialized.NotifyCollectionChangedEventArgs _
(Specialized.NotifyCollectionChangedAction.Reset))
End Set
End Property
Public ReadOnly Property PlugInUI As System.Windows.Controls.UserControl Implements
Contract.API.IPlugIn.PlugInUI
Get
Dim myUI As New UserControl1
Return myUI
End Get
End Property
Public Event PropertyChanged(sender As Object, e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Public Sub OnPropertyChanged(Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New
ComponentModel.PropertyChangedEventArgs(propertyName))
End Sub
Public Event CollectionChanged(sender As Object, e As
System.Collections.Specialized.NotifyCollectionChangedEventArgs) Implements
System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged
Public Sub OnCollectionChanged(args As
System.Collections.Specialized.NotifyCollectionChangedEventArgs)
RaiseEvent CollectionChanged(Me, args)
End Sub
End Class
导入System.ComponentModel.Composition
_
公共类UserControl1
实现Contract.API.IPlugIn、System.ComponentModel.INotifyPrope
Public Sub OnImportsSatisfied() Implements
System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
For Each plugInItem In WidgetList
Desktop.Children.Add(plugInItem)
Next
End Sub