I want to choose which user control to load but my MainWindowView is not even loaded yet so the region manager does not know any regions, How can I achieve this?
my bootstrapper looks like this:
protected override DependencyObject CreateShell()
{
return this.Container.Resolve<MainWindowView>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
this.Container.RegisterTypeForNavigation<WorkTypeSelectionView>();
}
and my viewmodel:
public MainWindowViewModel(IEventAggregator eventAggregator, IRegionManager regionManager)
{
this.eventAggregator = eventAggregator;
this.regionManager = regionManager;
this.AuthenticateUser();
if (this.LoggedUser.AvailableWorkTypes.Count > 1)
{
this.Navigate(nameof(WorkTypeSelectionView));
}
}
private void Navigate(string obj)
{
this.regionManager.RequestNavigate(DefaultContentRegion, obj);
}
thanks in advance!
EDIT:
Guess i was asking the wrong question, found this https://stackoverflow.com/a/7887936/171136 still want to explore other options. Thanks!
You can use View Discovery with regionManager.RegisterViewWithRegion("RegionName", typeof(View));. When the region is created, it will automatically inject the view.
Related
In Prism 7 I can RegisterForNavigation and RequestNavigate from IModule like this:
public class ModuleAModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve<IRegionManager>();
regionManager.RequestNavigate("ContentRegion", "PersonList");
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<PersonList>();
}
}
and I know that I can RegisterForNavigation from PrismApplication like this:
public partial class App : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA>();
}
}
but how can I RequestNavigate from PrismApplication immediately on start?
I have tried this:
public class MainWindowViewModel : BindableBase
{
public MainWindowViewModel(IRegionManager regionManager)
{
regionManager.RequestNavigate("ContentRegion", "ViewA");
}
}
but this.regions.Count is 0 in RegionManager from Prism
private IRegion GetRegionByName(string regionName)
{
return this.regions.FirstOrDefault(r => r.Name == regionName);
}
"ContentRegion" definitely exists, because it works if I try from the IModule and I know that RegisterTypes from PrismApplication executes before the MainWindowViewModel constructor.
I don't know what I am missing and I can't find the answer in any examples or tutorials.
Thank you for your help!
Your best bet is to override OnInitialized in your application and do the navigation there. You can access the container to fetch the region manager through the Container property.
If you use a bootstrapper, you can override InitializeModules and navigate there.
My code looks like this:
Bootstrapper.cs
public class Bootstrapper : BootstrapperBase
{
private SimpleContainer _container = new SimpleContainer();
public Bootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
base.OnStartup(sender, e);
DisplayRootViewFor<ShellViewModel>();
}
protected override void Configure()
{
_container.Singleton<IEventAggregator, EventAggregator>();
_container.Singleton<IWindowManager, WindowManager>();
_container.RegisterPerRequest(typeof(ShellViewModel), null, typeof(ShellViewModel));
}
protected override object GetInstance(Type service, string key)
{
return _container.GetInstance(service, key);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return _container.GetAllInstances(serviceType);
}
protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
}
And my ShellViewModel looks like this:
ShellViewModel.cs
public class ShellViewModel : Conductor<Screen>
{
public ShellViewModel
{
var aViewModel = IoC.Get<AViewModel>();
ActivateItem(aViewModel);
}
}
But whenever I run the program, a blank screen is shown. When I debug it, it said that the aViewModel is null.
Is there anything wrong with the Bootstrapper?
Based on the code provided, AViewModel is not registered with the container in the Bootstrapper so IoC does not know it exists, thus it will return null when requested to Get that type
For example
_container.RegisterPerRequest(typeof(AViewModel), null, typeof(AViewModel));
All types that need to be resolved by IoC should first be registered with the backing container.
I have a MainWindow which only contains the region for displaying other Views:
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion"/>
What I am trying to do, is to immediately when my MainWindowViewModel loads, to navigate to MainPageViewModel.
I have tried to implement interface INavigationAware such as following:
public void OnNavigatedTo(NavigationContext navigationContext)
{
_regionManager.RequestNavigate("ContentRegion", App.Experiences.DetailPage.ToString());
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
_regionManager.RequestNavigate("ContentRegion", App.Experiences.DetailPage.ToString());
}
But even when I set my breakpoints over these, they are never executed.
What am I doing wrong?
EDIT
Maybe I need to change my Bootstrapper logic? Here is how it looks like:
public class Bootstrapper: UnityBootstrapper
{
protected override System.Windows.DependencyObject CreateShell()
{
return Container.TryResolve<MainWindow>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType(typeof(IDataRepository), typeof(DataRepository), null,new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());
Container.RegisterTypeForNavigation<MainPage>(App.Experiences.MainPage.ToString());
Container.RegisterTypeForNavigation<DetailPage>(App.Experiences.DetailPage.ToString());
}
}
I had to edit my Bootstrapper logic such as following:
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
Prism.Regions.IRegionManager newRegion = Container.TryResolve<Prism.Regions.IRegionManager>();
newRegion.RequestNavigate("ContentRegion", App.Experiences.MainPage.ToString());
}
Recently I took an interest in developing PRISM WPF applications. Now I'm trying to load my modules from a DLL I make after building the Modules Project (Wpf User Control Library). During the build of the modules project I copy the DLL in the debug folder (copy: xcopy /y "$(TargetPath)" "$(SolutionDir)FooBar\$(OutDir)Modules\"). Next I configure the bootstrapper and I think there is were I lost it.
I'll attach my code below.
Bootstrapper
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
var shell = ServiceLocator.Current.GetInstance<Shell>();
return shell;
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)this.Shell;
App.Current.MainWindow.Show();
}
protected override IModuleCatalog CreateModuleCatalog()
{
return base.CreateModuleCatalog();
}
protected override void ConfigureModuleCatalog()
{
var moduleCatalog = new DirectoryModuleCatalog();
moduleCatalog.ModulePath = Environment.CurrentDirectory + #"\Modules";
ModuleCatalog = moduleCatalog;
}
protected override void InitializeModules()
{
base.InitializeModules();
}
protected override ILoggerFacade CreateLogger()
{
return base.CreateLogger();
}
}
Shell.xaml.cs
protected readonly IModuleCatalog _moduleCatalog;
public Shell(IModuleCatalog moduleCatalog)
{
this._moduleCatalog = moduleCatalog;
InitializeComponent();
}
App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
ViewModelBase
public abstract class ViewModelBase : INotifyPropertyChanging, INotifyPropertyChanged,IModule
{
//Implementation INotify etc..
public void Initialize()
{
}
}
So I'm wondering why my ModuleCatalog.Modules is always 0. Can someone help me out ?
Is your module catalog null? or contains no module?
check that Environment.CurrentDirectory + #"\Modules"; returns the correct path and all DLL are in.
Do you really need to load them from dir? Don't you know which modules will be loaded?
I usualy do that:
public partial class Bootstrapper: UnityBootstrapper
{
protected override void ConfigureContainer()
{
base.ConfigureContainer();
}
protected override IModuleCatalog CreateModuleCatalog()
{
// Create the module catalog from a XAML file.
return Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri("/Shell;component/ModuleCatalog.xaml", UriKind.Relative));
}
protected override DependencyObject CreateShell()
{
// Use the container to create an instance of the shell.
ShellView view = Container.TryResolve<ShellView>();
// Display the shell's root visual.
//view.ShowActivated = false;
view.Show();
return view;
}
}
and my modulecatalog
<prism:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
<prism:ModuleInfo Ref="Connexion.dll"
ModuleName="Connexion"
ModuleType="Connexion.ModuleInit, Connexion, Version=1.0.0.0" />
<prism:ModuleInfo Ref="Tools.dll"
ModuleName="Tools"
ModuleType="Tools.ModuleInit, Tools, Version=1.0.0.0" />
<prism:ModuleInfo Ref="DrawingModule.dll"
ModuleName="DrawingModule"
ModuleType="DrawingModule.ModuleInit, DrawingModule, Version=1.0.0.0"
InitializationMode="WhenAvailable">
<prism:ModuleInfo.DependsOn>
<sys:String>Connexion</sys:String>
<sys:String>Tools</sys:String>
</prism:ModuleInfo.DependsOn>
</prism:ModuleInfo>
<prism:ModuleInfo Ref="Sis.dll"
ModuleName="Sis"
ModuleType="Sis.ModuleInit, Sis, Version=1.0.0.0"
InitializationMode="WhenAvailable">
<prism:ModuleInfo.DependsOn>
<sys:String>Connexion</sys:String>
<sys:String>Tools</sys:String>
<sys:String>DrawingModule</sys:String>
</prism:ModuleInfo.DependsOn>
</prism:ModuleInfo>
and all modules have the buildAction: copy "$(TargetPath)" "$(SolutionDir)Shell\$(OutDir)"
How to create custom bindings for Windows Phone?
I need to do something like this (but this example for Android):
answer
Custom bindings in Android:
public class LongClickEventBinding
: MvxBaseAndroidTargetBinding
{
private readonly View _view;
private IMvxCommand _command;
public LongPressEventBinding(View view)
{
_view = view;
_view.LongClick += ViewOnLongClick;
}
private void ViewOnLongClick(object sender, View.LongClickEventArgs eventArgs)
{
if (_command != null)
{
_command.Execute();
}
}
public override void SetValue(object value)
{
_command = (IMvxCommand)value;
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
_view.Click -= ViewOnLongClick;
}
base.Dispose(isDisposing);
}
public override Type TargetType
{
get { return typeof(IMvxCommand); }
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.OneWay; }
}
}
Excuse me for the improper question..
As far as I understood your question, you don't need to develop anything at all. Use Blend to apply & setup CallMethodAction built-in behavior, and implement public method in your VM class.
WP7 doesn't expose Tap and Hold as an event.
However, I believe you can access this sort og thing in Wp7 and Wp8 using Gestures - e.g.
http://blogs.claritycon.com/windowsphone7/2010/07/wp7-gesture-recognizer-and-behavior-triggers/
http://www.windowsphonegeek.com/articles/WP7-GestureService-in-depth--key-concepts-and-API