2013-09-07 2 views
1

Я новичок в MEF и начал проект по его тестированию. Я пытаюсь открыть MainForm, который будет загружать плагины на основе интерфейса. Эти плагины должны иметь возможность обмениваться информацией между ними, и MainForm должен иметь возможность общаться со всеми из них. Поэтому я начал с создания моего MainForm, который загружает плагин. Плагин - это только форма, содержащая ListBox. На MainForm у меня есть кнопка. Я хочу, чтобы эта кнопка отправила список (String) в плагин и этот плагин для загрузки этого списка (строки) в ListBox. В настоящее время, когда я нажимаю кнопку MainForm, он отправляет список в плагин. Но список не загружается в плагин ListBox. Чтобы найти проблему, я добавил новую кнопку в MainForm, чтобы убедиться, что свойство plugin действительно содержит список (строки), который я отправил. И да, список содержит все мои строки. Проблема должна быть в том, что ListBox не освежает?Обновления свойств MEF и PlugIn

Часть интерфейса:

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 

Код плагиновой XAML:

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

В чем проблема? Я искал в Интернете примеры и нашел сотни, но ни один из них не показывает, как делать то, что я хочу делать. Как раз перед отправкой моего вопроса здесь я добавил INotifyPropertyChanged, он не разрешил проблему. Было бы лучше для меня использовать PRISM, Caliburn.Micro или MEF только будет хорошо?

Благодарим за помощь!

ответ

1

Спасибо всем!

Наконец-то я нашел ответ.

Я реализовал PRISM EventAggregator и меняла следующий

В интерфейсе и 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 

А теперь все работает, как я хотел!

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 

Мне нужно, чтобы свойство Files отображалось в списке PlugB ListBox.

Еще раз спасибо за помощь!

+0

Я продолжаю пробовать много вещей и нашел что-то действительно странное. Я добавил кнопку HostApp, которая получает количество строк в Plugin файла и возвращает количество строк правильно. Я также добавил кнопку в PlugIn, чтобы получить количество строк в файлах, и он возвращает 0! Почему подключаемый модуль существует в «двух разных экземплярах» один в хосте и один плагин? – Chris

Смежные вопросы