I think the latest version of Mvvmcross, 3.0.14, may have an anomaly in setting up the Application_Launching override of a WP phone application. Previous versions would add in:
RootFrame.Navigating += RootFrameOnNavigating;
With the implementation of RootFrameOnNavigating doing the magic of hooking into the mvx framework so that your App.Initialize and subsequent RegisterAppStart of a viewmodel would setup your first page. With this implementation missing, you start with the page defined in WMAppManifest.
To be complete, here is the previous implementation of RootFrameOnNavigating that I no longer see when setting up a new WP project with mvvmcross vis Nuget:
private void RootFrameOnNavigating(object sender, NavigatingCancelEventArgs args)
{
args.Cancel = true;
RootFrame.Navigating -= RootFrameOnNavigating;
RootFrame.Dispatcher.BeginInvoke(() => { Cirrious.CrossCore.Mvx.Resolve<Cirrious.MvvmCross.ViewModels.IMvxAppStart>().Start(); });
}
Nothing has changed in this area.
Previous versions would not add in that code.
Adding this code has always been the responsibility of the app developer - it's never been part of the nuget setup - see the todo list in the current nuget package %20Windows%20Phone%20UI.txt">https://github.com/MvvmCross/MvvmCross/blob/v3/nuspec/PhoneContent/%20Windows%20Phone%20UI.txt
Related
I'm attempting to create a version of the UWP app for the TipCalc sample here: https://github.com/MvvmCross/MvvmCross-Samples/tree/master/TipCalc
There already is a UWP version in the sample, which works fine. However I'm attempting to use Template10 (https://github.com/Windows-XAML/Template10) and I am having trouble getting the two libraries to work together.
MvvmCross wants me to modify the OnLaunched method, which has a reference to the root Frame. However, Template 10 instead abstracts this method exposing OnStartAsync which has no such reference...
There is an override in Template 10 for CreateRootFrame which seems like the right place to initialize the mvvmcross app, but this doesn't appear to work the way I expected...
Although the launched app DOES navigate to the appropriate page, and does also appear to initialize the view model (a breakpoint on the Start method in the associated VM does get hit), the page itself is blank.
comparing the Visual Tree of both apps reveals that while the existing UWP app from the sample has a Frame:
my Template10 App is loading a Modal Dialog:
I forked the original sample project and added the template 10 version, if you wish to try it for yourself: https://github.com/selaromdotnet/MvvmCross-Samples
Has anyone else been able to integrate MvvmCross with template 10? do you have any idea what i'm doing wrong, and any advice for the best practices in using both of these libraries together?
hmm it turns out that the ModalDialog is the expected behavior for Template10, according to the current docs here: https://github.com/Windows-XAML/Template10/wiki/Docs-|-Bootstrapper
I'm not familiar enough with Template10 to say why this is the case, but it does also say you can change this by overriding OnInitializeAsync, which I did, restoring the original frame in the same way the regular UWP project does:
public override async Task OnInitializeAsync(IActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
var setup = new Setup(rootFrame);
setup.Initialize();
}
await Task.CompletedTask;
}
This did the trick! I'm sure I still have a ways to go (I believe Template10 has it's own way of restoring state, so I probably shouldn't be doing it here)...
but this at least change finally got me to a working app. IF you know more about what I'm doing incorrectly here or what I should be doing instead, your comments would be greatly appreciated, thanks!
I try to set up an project with MVVM Cross in Windows Phone 8.1 Universal App. I used this tutorial: https://github.com/MvvmCross/MvvmCross/wiki/Tip-Calc-A-Universal-Windows-App-UI-Project
Now I always get the following exception:
Program does not contain a static 'Main' method suitable for an entry point [Project].WindowsPhone
In the App Project is the entry point defined as App.cs In this class I only changed this:
var setup = new Setup(rootFrame);
setup.Initialize();
var start = Mvx.Resolve<IMvxAppStart>();
start.Start();
And this setup class:
public class Setup : MvxWindowsSetup
{
public Setup(Frame rootFrame) : base(rootFrame)
{
}
protected override IMvxApplication CreateApp()
{
return new Core.App();
}
}
Does anyone have an idea what's the reason for that? o.O
Thanks
NPadrutt
EDIT: I could solve it with creating a new project and add the hot tuna starter package. From there I added the Android and ios files from the other project one by one again.
The solution is to set the "Build Action" of your App.xaml file to "ApplicationDefinition".
If you did what I did, you at some point added an App.xaml file from scratch and this sets the build definition incorrectly.
I'm re-writing a Windows Phone app to make it cross platform using the excellent MvvmCross framework.
On Windows Phone I usually test DeviceNetworkInformation.IsNetworkAvailable to ensure I have a network connection before calling a REST service.
Is there a way of doing this in a cross-platform way using MvvmCross?
There is a cross-platform plugin Cirrious.MvvmCross.Plugins.Network specifically for Network functionality and this was originally built specifically to provide Reachability
However, sadly the WindowsPhone part of this isn't yet implemented! See https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Network/Cirrious.MvvmCross.Plugins.Network.Phone/Plugin.cs
If you need Reachability within a cross-platform app including WindowsPhone, I'd probably opt for adding this Network plugin, and then also modifying your WindowsPhone Setup to register something like:
public class MyReachability : IMvxReachability
{
public bool IsHostReachable(string host)
return // something using DeviceNetworkInformation.IsNetworkAvailable
}
}
// registered in Setup using:
protected override void InitializeLastChance() {
base.InitializeLastChance();
Mvx.RegisterType<IMvxReachability, MyReachability>();
}
Longer term, I'd be happy to see a decent implementation pushed back into the MvvmCross repository.
Also linking this question to: MvvmCross Reachability on Windows Phone and Network state with mvvmcross?
I develop a project that uses Castle Windsor WCF Integration Facility as DDD architecture. There are a single container project, single domain project, several implementation projects and an executable console. Dependency tree can be shown like below:
Console(exe) -> Container(windsor) -> { Implementations -> DomainInterfaces }
Console project invokes Container.Bootstrapper.Initialize() and castle installers search this assembly in this method. In debug mode, it works successfully, windsor loads all dependencies and creates WCF service. When cursor enters into Initialize, I can see newly loaded modules in Modules window.
Dependency installation code is shown below:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container = new WindsorContainer().AddFacility<WcfFacility>()
.Register
(
Component.For<IDataProvider>().Instance(new DataProvider(s_DataConfigurationElement)).LifeStyle.Singleton,
Component.For<IUserRepository>().ImplementedBy<UserRepository>().LifeStyle.Singleton,
Component.For<IDomainManager>().ImplementedBy<DomainManager>().LifeStyle.Singleton,
Component.For<IGateway>().ImplementedBy<Gateway>().LifeStyle.PerThread.AsWcfService()
);
}
Problem is in release mode. I could't set breakpoint to this method and installers couldn't work, so nothing was loaded in Modules Window. In release mode, it works only if code optimization is unchecked and full-pdb debug info is checked in the project options of Console project. Is this a known issue or bug?
Thanks in advance.
You should never reassign container parameter in installer class. It is mystery for me, why it worked in DEBUG mode.
Try this instead:
public void Install(IWindsorContainer container, IConfigurationStore store) {
container.AddFacility<WcfFacility>();
container.Register(
Component.For<IDataProvider>().Instance(new DataProvider(s_DataConfigurationElement)),
Component.For<IUserRepository>().ImplementedBy<UserRepository>(),
Component.For<IDomainManager>().ImplementedBy<DomainManager>(),
Component.For<IGateway>().ImplementedBy<Gateway>().AsWcfService());
}
In mvvmcross v3 ViewModel
public class TimerViewModel : MvxViewModel
{
System.Timers.Timer timer;
public TimerViewModel()
{
timer = new System.Timers.Timer(500f);
timer.Elapsed += HandleTimerElapsed;
timer.Start();
}
void HandleTimerElapsed (object sender, ElapsedEventArgs e)
{
Debug.Log( "Time Elapsed" );
}
}
As MvxViewModel doesn't implement IDisposable, where should I put the following code ?
timer.Stop();
timer.Elapsed += HandleTimerElapsed;
I find that mvvmcross code have some MvxWeakEventSubscription, is it used to solve my problem ?
There's no easy universal way to know when to dispose the ViewModel - especially once you start mixing and matching ViewModel presentation styles to include navigations, tabs, splitviews, flyouts, fragments, lists, etc. and as you include more and more platforms
As a result of this, a couple of ways I have shut things like timers down in the past are:
1. Sometimes I have used a specialised interface on the ViewModel and I ensure this is called appropriately on each client.
For example, I have done some starting/stopping of 'page' level Views using:
OnPause/OnResume in Android
OnNavigatedTo/OnNavigatingFrom in Windows
ViewDidAppear/ViewWillDisappear in iOS
I have thought about adding this as a generalised pattern to do this (it is logged in https://github.com/slodge/MvvmCross/issues/74) - but so far I've not added this to v3 as I think it would lead to too much misunderstanding among users - it's better to let them to do this in the very few situations where it's needed.
Update: I have blogged about this and published a sample - see http://slodge.blogspot.co.uk/2013/11/n42-is-my-viewmodel-visible-can-i-kill.html
2. Sometimes I've just used Event Aggregation through the MvvmCross Messenger - and I've used it's inherent WeakReference-based messaging to make sure the ViewModel can be garbage collected when the view has finished with it.
An example of this is in the InternetMinute sample - which has a single 'Tick generation service' which ViewModels can connect to via messaging for updates - see:
the service - https://github.com/slodge/MvvmCross-Tutorials/tree/master/InternetMinute/InternetMinute.Core/Services/Tick
a ViewModel that consumes the service - via https://github.com/slodge/MvvmCross-Tutorials/blob/master/InternetMinute/InternetMinute.Core/ViewModels/HomeViewModel.cs
You might consider this slightly inefficient - as the Tick messages will be generated even if the ViewModel isn't present - but it's only a small inefficiency.
3. I've considered using more final events - things like OnNavigatingFrom(BACK) and 'onDestroy' and some 'final' detection on the UINavigationController delegates ... but I've not had a reason to do this 'for real' on any project yet.