I have a Module called ModuleMenu. In this module I have a UserControl called MenuView and a Corresponding ViewModel called UserControlViewModel. I also have a class called Module. All the code is as given below:
MenuView.xmal
<UserControl ..............>
<ListBox ItemsSource="{Binding MenuItems, Converter={StaticResource dummy}}" DisplayMemberPath="MenuItemName" SelectedItem="{Binding SelectedMenuItem}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="10,0" />
</Style>
</ListBox.Resources>
</ListBox>
</UserControl>
MenuView.xaml.cs
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MenuView : UserControl
{
public MenuView()
{
InitializeComponent();
}
}
UserControlViewModel.cs
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MenuViewModel : ViewModelBase
{
IServiceFactory _ServiceFactory;
[ImportingConstructor]
public MenuViewModel(IServiceFactory serviceFactory)
{
_ServiceFactory = serviceFactory;
}
protected override void OnViewLoaded()
{
_MenuItems = new ObservableCollection<MenuItem>();
WithClient<IMenuItemService>(_ServiceFactory.CreateClient<IMenuItemService>(), menuItemClient =>
{
MenuItem[] menuItems = menuItemClient.GetAllParentMenuItemsWithChildren();
if (menuItems != null)
{
foreach (MenuItem menuItem in menuItems)
{
_MenuItems.Add(menuItem);
}
_SelectedMenuItem = _MenuItems[2];
}
});
}
private ObservableCollection<MenuItem> _MenuItems;
public ObservableCollection<MenuItem> MenuItems
{
get
{
return _MenuItems;
}
set
{
if (_MenuItems != value)
{
_MenuItems = value;
OnPropertyChanged(() => MenuItems, false);
}
}
}
private MenuItem _SelectedMenuItem;
public MenuItem SelectedMenuItem
{
get
{
return _SelectedMenuItem;
}
set
{
if (_SelectedMenuItem != value)
{
_SelectedMenuItem = value;
OnPropertyChanged(() => SelectedMenuItem);
}
}
}
}
Module.cs
[ModuleExport(typeof(Module), InitializationMode=InitializationMode.WhenAvailable)]
public class Module : IModule
{
IRegionManager _regionManager;
[ImportingConstructor]
public Module(IRegionManager regionManager)
{
_regionManager = regionManager;
}
public void Initialize()
{
_regionManager.Regions[RegionNames.MenubarRegion].Add(ServiceLocator.Current.GetInstance<MenuView>());
}
}
Now in my main Project I have a class called BootStrapper.cs as follows:
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(Bootstrapper).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleMenu.Module).Assembly));
}
}
In my App.xaml:
<Application ..............>
<Application.Resources>
<DataTemplate DataType="{x:Type modMenu:MenuViewModel}">
<modMenu:MenuView />
</DataTemplate>
</Application.Resources>
</Application>
And finally in App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}
When I run the application I get shell as expected. It shows me MenuView, but the data in MenuView is not loaded. I tried to debug it using a dummy converter and show that the viewModel is never initialized.
So, now my question is how can I initialize the viewModel?
update:
After trying your code I get exception as follows:
An exception has occurred while trying to add a view to region 'MenubarRegion'.
- The most likely causing exception was was:
'Microsoft.Practices.ServiceLocation.ActivationException: Activation
error occured while trying to get instance of type MenuView, key "" --->
Microsoft.Practices.ServiceLocation.ActivationException: Activation
error occured while trying to get instance of type MenuView, key ""
at Microsoft.Practices.Prism.MefExtensions.MefServiceLocatorAdapter
.DoGetInstance(Type serviceType, String key)
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
.GetInstance(Type serviceType, String key)
--- End of inner exception stack trace ---
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
.GetInstance(Type serviceType, String key)
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
.GetInstance(Type serviceType)
at Microsoft.Practices.Prism.Regions.RegionViewRegistry
.CreateInstance(Type type)
at Microsoft.Practices.Prism.Regions.RegionViewRegistry
.<>c__DisplayClass1.<RegisterViewWithRegion>b__0()
at Microsoft.Practices.Prism.Regions.Behaviors
.AutoPopulateRegionBehavior
.OnViewRegistered(Object sender, ViewRegisteredEventArgs e)'.
But also check the InnerExceptions for more detail or call
.GetRootException().
When I take a look at inner exception, I get the following error message:
{"Activation error occured while trying to get instance of type MenuView, key \"\""}
update2:
Here is the Export of type ServiceFactory :
[Export(typeof(IServiceFactory))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ServiceFactory : IServiceFactory
{
public T CreateClient<T>() where T : IServiceContract
{
return ObjectBase.Container.GetExportedValue<T>();
}
}