How to navigate from one ViewModel to another in Caliburn.Micro? - silverlight-4.0

I want to navigate from a login screen to the dashboard in my Silverlight OOB app.
I started using Caliburn.Micro but now I'm having doubts seeing as all I can use is the Conductor. Or am I missing something?
Note: I changed constructor to Conductor as originally intended. This is what you get for not proofreading your questions.

There are several ways you could display a login screen, probably the nicest is to initiate it from your ShellViewModel. So, your ShellViewModel would have a dependency on your LoginViewModel, which you could inject as an abstraction (ILoginViewModel), or better still use an abstract factory instead, and inject that into your ShellViewModel constructor.
Either way, once you have an instance of your LoginViewModel in the ShellViewModel, you can display it either as a modal dialog box (in which case use the Caliburn.Micro WindowManager.ShowDialog method - inject this dependency as an IWindowManager abstraction), or display the login view as part of your shell views main content area, in which case your ShellViewModel would be a conductor, and will activate an instance of your LoginViewModel with the ActivateItem method.
Once you have received input from your LoginViewModel, either as a modal dialog or conducted view, you can display your DashboardViewModel as appropriate using the ShellViewModel as a conductor.

Related

'Global' parent selector: limiting scope of any selector to a certain parent

Im looking for an option to limit the scope of every selector to a parent selector.
Am trying to abstract away a lot of the (internal implementation) details of our WebApp for the testers that will actually write the UI tests.
If our application shows a Modal dialog (just a div tag that lies op top of all the other content and prevents interacting with the underlying content), I'd like to restrict all Selectors used in the tests written by testers to be automatically limited to the scope of this Modal Dialog div.
Our new client UI framework uses just divs for Modal Dialogs, while our previous client UI framework used an embedded iframe for each modal dialog. In the iframe scenario, we'd call .switchToIframe(), which would effectively limited all selectors used in tests to this iframe.
Am trying to achieve something similar for the new client framework that uses just divs
I'm not sure you can limit the scope of the DOM like that, but you could build out a Page Object Model (POM) design that would only intelliSense existing locators from their respected repos. This way, if they begin typing a locator and it doesn't pop up, a hint that they aren't in the 'scope' of the modal.

Managing Angular 5 layout with a service

In an angular5 application, I have various sections of my page layout that I would like to control through an angular service. For example, I have a sidenav component that displays when a value is set to open, and I would like to be able to toggle it from any component I'd like.
My initial thought was that it would be nice if I could bind the open value to a variable in a LayoutService I would create, and the LayoutService would contain a toggle() method that would toggle the value and cause the sidenav to open/close. I could then inject my LayoutService into any component I'd like and control various parts of my layout.
Any idea whether this is possible and how I could go about doing this? I thought it might be possible using an EventEmitter or something, but I was wondering whether there was a simpler way and I'd rather not use redux.
https://stackblitz.com/edit/angular-lj7gsz
Here's a side-bar you can open and close using simple rxjs objects.
In the side-bar service, I've created a BehaviorSubject that you can pass boolean values to and I also exposed an Observable, which will emit every time a new value is passed to that subject.
By subscribing to that observable (I've used the async pipe to subscribe for me), my side-bar component will know when other components wish to open or close the side-bar. All the other components need to do is inject the service and call the service's open or close methods.
It's not perfect, but I feel it's definitely better than using event emitters as they were never made to be used in services.
Hopefully this is helpful.

Caliburn Micro navigation service resulting in nullreference exception

I am using the ViewModel First approach and i have trouble navigating from one ViewModel to another.
For example, i have two folders, View and ViewModels and i have two files in each Page1View.xaml, Page2View.xaml and Page1ViewModel.cs, Page2ViewModel.cs
In my app launch i have this the line below and it works perfectly fine.
DisplayRootViewFor<Page1ViewModel>();
Now on a button click from Page1ViewModel event when i add the line below, i get a null reference exception.
_navigationService.NavitageToViewModel<Page2ViewModel>();
Am i missing something here? To give more information, This is a UWP application and the container that i am using is WinRTContainer and i have registered both the ViewModels.
You are taking a ViewModel-first approach. Note that DisplayRootViewFor doesn't create a Frame control and doesn't set up a NavigationService.
Have a look at:
https://github.com/Caliburn-Micro/Caliburn.Micro/issues/126
Either switch to a View-first approach, or in your root view, setup a NavigationService passing a Frame to it:
container.RegisterNavigationService(rootFrame);

Use locator to manage multiple view-viewmodel pairs in Panorama Page

I'm new to Silverlight/MVVM. I tried some example of MVVM Light, it looks great.
For my scenario, I want to create a Panorama Page, for each Panorama Item, showing my usercontrol, a item list for a customer.
I've built usercontrol(view), viewmodel and WCF service model and works well in a single Panorama Item(Only use first customer).
Also, I use Locator of MVVM Light shown in MIX10 demo, it enables me to make design time data for Expression Blend.
My viewmodel will receive a parameter of customer ID then exchange data with WCF based on this ID.
And the customer list also comes from WCF. So I can't actually makes viewmodels in Locator's static constructor.
If viewmodels are built in runtime by calling Locator, how to make data binding?
The only way I think about is to make viewmodel object in usercontrol's constructor and make it datacontext.
Is there a better solution?
If you want to keep the same declarative model in the XAML, you can put a CurrentCustomerViewModel property on the locator and then set property to the right viewmodel before you navigate to the page.
Personally though for pages like that I typically put a viewmodel factory method on the locator (so it can cache them, etc) and call it from the OnNavigatedTo method, something like this.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
string id = NavigationContext.QueryString["customerID"];
vm = ViewModelLocator.GetCustomerViewModel(id);
DataContext = vm;
base.OnNavigatedTo(e);
}
Then I just use Blend's sample data capabilities for design time data. This way also helps support pinning the page to the start screen since that will be the entry point to the app and I won't necessarily get a good chance to set the "CurrentCustomerVM" property anyway.

ShowDialog a RadWindow with MVVMLight

I have a functional MVVM patterned SL app with a RadWindow (essentially a ChildWindow), that I would like to remove the code-behind in my view that shows the window using its ShowDialog. Both the main view and the window is bound to the same ViewModel if that helps.
The button has both a ViewModel command using a MVVMLight RelayCommand to handle setting state as well as the event handler in the View.
The ultimate solution/pattern will be reused 20+ times so something better than code-behind would be great.
Thoughts?
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
var window = new RadWindowTest.Controls.ChildWindow1();
window.Closed += new System.EventHandler<Telerik.Windows.Controls.WindowClosedEventArgs>(window_Closed);
window.ShowDialog();
}
In this case I would suggest you implement DialogService. This service you can inject into your view model, for testing you will have to inject an instance that does not depend on the view, thus maintaining testability. You can use the ViewModelLocator to make this service available to your application.
Another approach would be to implement a ViewBase class that implements an interface that allows you to display the dialog. This interface is now used by the ViewModel to display a dialog. Again to test you need to provide a different implementation of the interface. A sample can be found here.
Both ideas revolve around the same concept of factoring out the function that shows the dialog. In order to strictly de-couple the View and the ViewModel you will have to think about how the ViewModel specifies which dialog has to be shoen, and how the dialog resut or dialog model is returned to the calling ViewModel.
Which approach is better is open to your judgement. Personally I prefer the first approach as I do not have to inherit the views from a common base class.
PS: Use a command to get to the point in your ViewModel where you want to show the dialog. Using a dialog service should need no code behind.