我是MEF的新手,并开始了一个项目来测试它。我要做的是打开一个基于接口加载插件的MainForm。这些插件需要能够在它们之间交换信息,并且MainForm也应该能够与所有这些插件进行通信。所以我开始创建加载插件的MainForm。该插件只是一个包含ListBox的表单。在MainForm我有一个按钮。我希望该按钮将List(of String)发送到插件,并使用该插件在ListBox中加载List(String)。目前,当我点击MainForm按钮时,它会将列表发送到插件。但该列表未在插件ListBox中加载。为了找到问题,我在MainForm上添加了一个新按钮,以验证插件属性实际上是否包含我发送的列表(字符串)。是的,该列表包含我的所有字符串。问题需要是ListBox没有刷新?
界面的一部分:
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
PlugIn XAML中的代码:
<ListBox Name="lstFiles" ItemsSource="{Binding Path=Files}"/>
有什么问题?我在互联网上搜索了一些例子,发现了数百个,但没有一个显示如何做我想做的事情。就在我在这里发布我的问题之前,我添加了INotifyPropertyChanged,它没有解决问题。使用PRISM,Caliburn.Micro或MEF只会更好吗?
感谢您的帮助!
答案 0 :(得分:1)
谢谢大家!
我终于找到了答案。
我实施了PRISM EventAggregator并确实更改了以下内容
在Interface and PlugIns中
完全删除
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 Sub OnImportsSatisfied() Implements
System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
For Each plugInItem In WidgetList
Desktop.Children.Add(plugInItem.PlugInView)
Next
End Sub
到
Public Sub OnImportsSatisfied() Implements
System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
For Each plugInItem In WidgetList
Desktop.Children.Add(plugInItem)
Next
End Sub
现在一切都按我想要的方式运作了!
答案 1 :(得分:0)
Athari,谢谢你的评论。
我确实将属性修复为ObservableCollection,但没有解决问题。似乎我错过了其他的东西。
这是完整的代码。
接口
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
的PlugIn
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
PlugIn 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
我需要在PlugIn ListBox中列出Files属性。
再次感谢您的帮助!