MEF和PlugIn属性更新

时间:2013-09-07 15:53:53

标签: wpf vb.net mef

我是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只会更好吗?

感谢您的帮助!

2 个答案:

答案 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属性。

再次感谢您的帮助!