2010-12-06 3 views
3

Ich bin ein Neuling im Bereich MEF und versuche herauszufinden, wie ich meine Prism 4.0-Anwendung strukturieren kann, um Ansichten zum Anzeigen von Modellen zu verbinden. Mein Anwendungsfall ist, dass ich ein Benutzersteuerelement in einem anderen Benutzersteuerelement geschachtelt habe. Ich möchte das geschachtelte Benutzersteuerelement mit seinem Ansichtsmodell verbinden. Ich habe versucht, Prism 4.0-Beispielen zu folgen, bin mir jedoch nicht sicher, ob ich MEF-Best Practices verwende.Verschachtelte Ansicht zum Anzeigen eines Modells in Prism 4.0 und MEF

Hier sind einige Auszüge aus meiner Anwendung, um das Problem zu demonstrieren. HomeView verfügt über ein geschachteltes Benutzersteuerelement namens HelloView. Ich muss HelloView mit seinem Ansichtsmodell HelloViewModel verbinden. Der Code in seinem aktuellen Zustand funktioniert nicht. Ich denke, dass HelloView nicht von MEF erstellt wird und daher HelloViewModel nicht verbunden ist.

***** HomeModule ***** 
[ModuleExport(typeof(HomeModule))] 
public class HomeModule : IModule 
{ 
    IRegionManager _regionManager; 

    [ImportingConstructor] 
    public HomeModule(IRegionManager regionManager) 
    { 
     _regionManager = regionManager; 
    } 

    public void Initialize() 
    { 
     // Create the view 
     IHomeView homeView = ServiceLocator.Current.GetInstance<IHomeView>(); 

     // Add it to the region 
     IRegion region = _regionManager.Regions["MainRegion"]; 
     region.Add(homeView, "HomeView"); 
     region.Activate(homeView); 
    } 
} 


****** IHomeView ***** 
public interface IHomeView 
{ 
} 


***** HomeView.xaml ***** 
<UserControl ...> 

    <Grid x:Name="LayoutRoot"> 
     <view:HelloView x:Name="helloView"/> 
    </Grid> 

</UserControl> 


***** HomeView.xaml.cs ***** 
[Export(typeof(IHomeView))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class HomeView : UserControl, IHomeView 
{ 
    public HomeView() 
    { 
     InitializeComponent(); 
    } 
} 


***** IHelloView ***** 
public interface IHelloView 
{ 
} 


***** HelloView.xaml ***** 
<UserControl ...> 
    <StackPanel x:Name="LayoutRoot" Margin="10"> 
     <StackPanel Orientation="Horizontal" VerticalAlignment="Top"> 
      <TextBlock Text="Name" VerticalAlignment="Center" /> 
      <TextBox Width="100" VerticalAlignment="Center" Margin="10 0 0 0" 
        Text="{Binding Path=Name, Mode=TwoWay}" /> 
      <Button Content="Submit" VerticalAlignment="Center" Margin="10 0 0 0" 
        Command="{Binding SubmitCommand}"/> 
     </StackPanel> 
     <TextBlock Text="{Binding Message}" Margin="0 10 0 0" Foreground="Red" /> 
    </StackPanel> 
</UserControl> 

***** HelloView.xaml.cs ***** 
[Export(typeof(IHelloView))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public partial class HelloView : UserControl, IHelloView 
{ 
    public HelloView() 
    { 
     InitializeComponent(); 
    } 

    [Import] 
    public IHelloViewModel ViewModel 
    { 
     set { this.DataContext = value; } 
    } 
} 


***** IHelloViewModel ***** 
public interface IHelloViewModel 
{ 
} 


***** HelloViewModel ***** 
[Export(typeof(IHelloViewModel))] 
[PartCreationPolicy(CreationPolicy.NonShared)] 
public class HelloViewModel : NotificationObject, IHelloViewModel 
{ 
    public HelloViewModel() 
    { 
     this.SubmitCommand = new DelegateCommand<object>(this.OnSubmit); 
    } 

    private void OnSubmit(object obj) 
    { 
     Message = "Hello " + Name; 
    } 

    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if (value != _name) 
      { 
       _name = value; 
       this.RaisePropertyChanged("Name"); 
      } 
     } 
    } 

    private string _message; 
    public string Message 
    { 
     get { return _message; } 
     set 
     { 
      if (value != _message) 
      { 
       _message = value; 
       this.RaisePropertyChanged("Message"); 
      } 
     } 
    } 

    public ICommand SubmitCommand { get; private set; } 
} 

Antwort

1

Ihre Lösung ist in Ordnung, ich habe nur zwei Hinweise: Erstens: Wenn Ihr Katalog mehr als 1 Art von IHelloViewModel enthält (das ist sehr wahrscheinlich, weil Sie entsprechend mehr Ansichten und Viewmodel hat), dann Sie eine Komposition erhalten Fehler, da der Import mehr als ein Ergebnis zurückgibt.

[Import]public IHelloViewModel ViewModel 

sollte so etwas wie

[Import(typeof(HelloViewModel))] IHelloViewModel ViewModel 

sein, oder Sie gerade Ihre Immobilie machen wie:

[Import] 
public HelloViewModel ViewModel 

Zweitens: Verwenden Sie nicht ServiceLocator für die Erstellung Ihrer HomeView. ServiceLocator soll die Singleton-Instanzen erstellen und EventAggregator ist der perfekte Kandidat dafür. Ansichten sollten nicht geteilt werden (und Sie korrekt als [PartCreationPolicy(CreationPolicy.NonShared)] markiert - sonst ist Sie Ihre Ansicht in eine andere Region Sie Fehler erhalten hinzuzufügen.) )

Verwendung

[Import] 
    public HomeView HomeView 

Hoffnung, das hilft.

+0

Danke grimcoder! Gute Tipps. Ich denke, mein ursprünglicher Post hat nicht klar gemacht, dass der Code tatsächlich nicht funktioniert - HelloView wird nicht mit HelloViewModel verbunden. Ich vermute, dass die Konstruktion von HelloView nicht durch MEF geht. Was ist der beste Weg, diese Verbindung herzustellen? – Naresh

+0

Von Ihrem Code kann ich nicht sehen, warum Ihre ViewModel-Eigenschaft nicht abgeholt wird, Ihr Code ist unvollständig - IHelloViewModel fehlt. Außerdem empfiehlt PRISM, die View/ViewModel-Zuordnung innerhalb der Module Initialise() -Methode vorzunehmen. – grimcoder

+0

Ich habe den Code IHelloViewModel zu meinem ursprünglichen Beitrag hinzugefügt - es ist nur eine leere Schnittstelle. Ich hatte gehofft, dass MEF Verbindungsansichten erlauben würde, um Modelle mehr automatisch anzuzeigen (anstatt sie manuell in der Modulinitialisierungsmethode zu machen). – Naresh

Verwandte Themen