2015-02-24 28 views
0

我正在使用Prism + MEFMEF - 將視圖添加到shell區域不會將viewModel插入到視圖中使用

我有相當簡單的應用程序。 我有一個區域「Region1」的外殼。 將模塊作爲單獨項目與MyUserControl.xamlMyUserControlVM.csModuleA.cs。這個用戶控件必須在Shell - > Region1中顯示。爲此,我已將此用戶控件添加到ModuleA.cs

的區域中。現在MyUserControlVM未注入到UserControlDatacontext中。

[ModuleExport(typeof(ModuleA))] 
    public class ModuleA : IModule 
    { 
     public void Initialize() 
     { 
      var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>(); 

      regionManager.Regions["Region1"].Add(new MyUserControl()); 
     } 
    } 

MyuserControl.Xaml

<StackPanel> 
    <Label Content="{Binding Message}" Height="38" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" Width="193" Background="#FFD8CFCF" /> 
    <Label Content="ABC"></Label> 
</StackPanel> 

MyUserControl.Xaml.cs

public partial class MyUserControl : UserControl 
    { 
     public MyUserControl() 
     { 
      InitializeComponent(); 
     } 

     [Import] 
     public MyUserControlVM ViewModel 
     { 
      get { return this.DataContext as MyUserControlVM; } 
      set { this.DataContext = value; } 
     }   
    } 

MyUserControlVM.cs在Shell.Xaml定義

[Export(typeof(MyUserControlVM))] 
    [PartCreationPolicy(CreationPolicy.NonShared)] 
    public class MyUserControlVM : INotifyPropertyChanged 
    { 
     private string _message; 

     public string Message 
     { 
      get { return _message; } 
      set 
      { 
       _message = value; 
       NotifyPropertyChanged("Message"); 
      } 
     } 


     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged(string propertyName) 
     { 
      if(PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

地區:

<Grid> 
    <ContentControl Name="Region1" regions:RegionManager.RegionName="Region1" Margin="70"> 
      </ContentControl> 
</Grid> 

App.xaml.cs是這樣

 protected override void OnStartup(StartupEventArgs e) 
     { 
      base.OnStartup(e); 
      var bootstrapper = new Bootstrapper(); 
      bootstrapper.Run(); 
     } 

引導程序是這樣的

public class Bootstrapper : MefBootstrapper 
    { 
     protected override DependencyObject CreateShell() 
     { 
      return Container.GetExportedValue<Shell>(); 
     } 

     protected override void InitializeShell() 
     { 
      base.InitializeShell(); 
      App.Current.MainWindow = (Window)Shell; 
      App.Current.MainWindow.Show(); 
     } 

     protected override void ConfigureAggregateCatalog() 
     { 
      base.ConfigureAggregateCatalog(); 

      AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Shell).Assembly)); 
      AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleLibrary.ModuleA).Assembly)); 

     } 

    } 

請幫我在哪裏,我做錯了。

回答

0

答案很簡單。

創建視圖(MyUserControl)的實例明確:

regionManager.Regions["Region1"].Add(new MyUserControl()); 

在這種情況下,MEF不參與對象的生命週期。

讓棱鏡爲你創建視圖實例,因此該對象可以通過IoC容器進行處理(包括部分組合物和依賴注射):

regionManager.RegisterViewWithRegion("Region1", typeof(MyUserControl)); 

此外,我建議你避免ServiceLocator反模式:

ServiceLocator.Current.GetInstance<IRegionManager>(); 

取而代之的是,使用依賴注入:

[ModuleExport(typeof(ModuleA))] 
public class ModuleA : IModule 
{ 
    private readonly IRegionManager regionManager; 

    [ImportingConstructor] 
    public ModuleA(IRegionManager regionManager) 
    { 
     this.regionManager = regionManager; 
    } 

    public void Initialize() 
    { 
     this.regionManager.RegisterViewWithRegion("Region1", typeof(MyUserControl)); 
    } 
} 
+0

謝謝!有一個問題,我可以做'Container.GetExportedValue ();'類似於'Container.GetExportedValue ();'在引導程序中? – Babu 2015-02-24 12:23:42

+0

@Babu,引導程序不是爲了創建用戶特定的應用程序邏輯對象,所以最好不要這樣做。你的'UserControl'是一個視圖,應該由Prism通過視圖註冊('RegisterViewWithRegion()'方法)或者通過導航('regionManager.RequestNavigate(「Region1」,「UserControl」))創建。 – dymanoid 2015-02-24 12:28:57

+0

哦..謝謝@dymanoid – Babu 2015-02-24 12:51:12