Search code examples
wpfvb.netmef

MEF and PlugIn properties updates


I'm new to MEF and started a project to test it. What I'm trying to do is opening a MainForm that would load plugins based on an Interface. Those plugins need to be able to exchange information between them and the MainForm should be able to communicate with all of them too. So I started by creating my MainForm that loads a plugin. The plugin is only a form containing a ListBox. On the MainForm I have a button. I want that button to send a List(of String) to the plugin and that plugin to load that List(of String) in the ListBox. Currently, when I click on the MainForm button, it sends the list to the plugin. But the list is not loading in the plugin ListBox. Looking to find the problem, I added a new button on the MainForm to verify that the plugin property actually contains the list(of string) I sent it. And yes, the list contains all my strings. The problem needs to be that the ListBox isn't refreshing?

Part of the interface:

Public Interface IPlugIn

   Property PlugInName as string
   Property Files As List(Of String)

End Interface

Code in the MainForm Button:

    Dim currentPlugIn As Contract.API.IPlugIn

    currentPlugIn = PlugIns.Find(Function(x) x.PlugInName = "Test")

    currentPlugIn.Files = IO.Directory.GetFiles("SomeFolder").ToList

Code in the PlugIn:

<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

Code in PlugIn XAML:

<ListBox Name="lstFiles" ItemsSource="{Binding Path=Files}"/>

What's the problem? I searched the Internet for examples and found hundreds, but none of them is showing how to do what I want to do. Just before posting my question here, I added the INotifyPropertyChanged, it didn't resolved the problem. Would it be better for me to use PRISM, Caliburn.Micro or is MEF only going to be okay?

Thanks for your help!


Solution

  • Thanks everyone!

    I finally found the answer.

    I implemented PRISM EventAggregator and did change the following

    In the Interface and PlugIns

    Completely removed

    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
    

    In the Host

    Changed

    Public Sub OnImportsSatisfied() Implements 
    System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
        For Each plugInItem In WidgetList
            Desktop.Children.Add(plugInItem.PlugInView)
        Next
    End Sub
    

    to

    Public Sub OnImportsSatisfied() Implements 
    System.ComponentModel.Composition.IPartImportsSatisfiedNotification.OnImportsSatisfied
        For Each plugInItem In WidgetList
            Desktop.Children.Add(plugInItem)
        Next
    End Sub
    

    And now everything works as I wanted!