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

MEF - Adding view to the shell region doesn't inject viewModel into view using

我正在使用 Prism + MEF

我的应用程序相当简单。 我有 shell,区域 "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

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

        }

    }

哪里做错了请大家帮帮我

答案很简单。

您显式创建视图实例 (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));
    }
}