MEF - 向shell区域添加视图不会将viewModel注入到视图中

时间:2015-02-24 11:31:56

标签: c# wpf prism mef

我正在使用Prism + MEF

我的应用相当简单。 我有一个区域" Region1"。 将模块作为具有MyUserControl.xamlMyUserControlVM.csModuleA.cs的单独项目。此用户控件必须显示在Shell中 - >区域1。为此,我已将此usercontrol添加到ModuleA.cs

中的区域

现在MyUserControlVM未注入UserControl Datacontext

    [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

    [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));
        }
    }

Shell.Xaml中定义的区域:

<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();
        }

BootStrapper就像这样

    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));

        }

    }

请在我做错的地方帮助我。

1 个答案:

答案 0 :(得分:0)

答案很简单。

您明确地创建了一个视图实例(MyUserControl):

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

在这种情况下,MEF不参与对象的生命周期。

让Prism为您创建视图实例,因此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));
    }
}