Seeking guidance on WPF Prism Multi display application - c#

I'm in the beginning stages of designing an application using Prism and have a question. In all the reference material I've been able to find, there is lots of details on creating a single screen application, but I have a requirements beyond that.
I would like the have two windows showing (Multi screen), both with the exact same layout but each looking at a difference source of information for their data. In other words, I have datasource A and datasource B that update very frequently and I need to monitor both of them at the same time.
Is there a way to launch a prism app multiscreen in this manner or would it better to launch separate processes for each source?
Thanks.

This should be pretty simple. Launching a new Window for each ought to do what you need (the user would have to move the window to the second monitor... I suppose you could investigate some p/invoke magic to move the window to the proper monitor if you wanted).
Do you need something more complicated?
If it's the same view with different data, I'd use MVVM and spin them off sort of like this:
MyFirstViewModel vm1 = new MyFirstViewModel();
MySecondViewModel vm2 = new MySecondViewModel();
MyView view1 = new MyView();
view1.DataContext = vm1;
MyView view2 = new MyView(vm2);
view2.DataContext = vm2;
view1.Show();
view2.Show();
Hopefully your view models can be reusable too so you wouldn't need to write a class for each, but hopefully this illustrates the strategy a little.

Related

Prism WPF: How to Open A New Window/Dialog

When using code behind, the code looks like this:
AnotherWindow x = new AnotherWindow();
x.Show() ;
// or x.ShowDialog()
But how can I achieve this using MVVM? Specifically Prism?
In case you need to build a dialog for asking user login input or progressing dialog, MahApps.Metro can be a useful toolkit as it provides you with some built-in dialog UI/functionalities with MVVM pattern. For more information, check some examples here:
https://mahapps.com/controls/dialogs.html
In Prism, there's the InteractionRequest for short-lived dialogs. If you're looking for a long living dialog, like a second application window or shell, you're stuck with new Window ... Show.
To make your dialog service mvvm-friendly, you should hide it behind an interface and make it as generic as possible. Using view model first here eliminates the need to specify a window type, because you can provide a default window that just contains one large ContentControl, and the view can be mapped as DataTemplate.

WPF, MVVM, and effective navigation / control flow

I am currently building an application based on a real world scenario, to help me learn and understand WPF and MVVM. To that end I have read and worked through Karl Shifflett's "In The Box" VSIX, and I was able to adapt most of the concepts to the application that I am working on.
While I think MVVM is a powerful design pattern, it does (seemingly) make things that were once trivial (e.g. displaying messages, navigation, interacting with multiple window), not so trivial or straightforward. Now onto the crux of my problem / confusion.
The WPF application that I am working on is a Windows based application, and I am working from a set of basic requirements:
A basic login screen
After a successful login, close the login screen and open the actual application
Simulate a typical program workflow (opening "child" windows via button clicks, displaying modal windows, etc.)
Preform data validation / error handling
Log out
I am used to working with MDI Applications on a windows platform where interactions on a parent form cause child forms to open; I understand that MDI is not something that WPF supports and I am fine with approaching development from a different perspective. My UI would still work in a similar manner to a MDI application though: I have my application layout, and as I interact with that layout my application will respond by opening windows, displaying messages, and so on. It isn't clear to me (via MVVM) how to interact with multiple windows, or how well MVVM would scale to a large application with many windows / views.
I am not opposed to using something like Prism, but I haven't found a good article on how Prism approaches my particular problem very well. Any help, advice, feedback, or otherwise is greatly appreciated!
Have you tried looking at nRoute Framework?
A link can be found here
There are actually some good tuturials about prism
Link 1
Link 2 (Part II of Link1)
Link 3
For a more straight forrward application (not very complex and modular), you can always create a aplication, with a main window that manages child usercontrols (login window, menu window, other windows ...)
For example, create a window a contentpresenter in it, and in codebehind:
public partial class ShellWindow: Window
{
public enum PagesTypes { Login, Home }
PagesTypes currentOpenedPage;
LoginUserControl login;
HomeUserControl home;
public WindowController()
{
InitializeComponent();
login = new LoginUserControl ();
login.GoToPage += new LoginUserControl.ChangePageHandler(GoToPage);
GoToPage(PagesTypes.Login);
}
public void GoToPage(PagesTypes page)
{
switch (page)
{
case PagesTypes.Login:
//Close last opened usercontrol,
....
//open new usercontrol
login = new LoginUserControl();
contentpresenter.content = login;
break;
//other pages cases
....
}
currentOpenedPage = page;
}
}
And in for example the login usercontrol:
public partial class LoginUserControl : UserControl
{
internal delegate void ChangePageHandler(ShellWindow.PagesTypes toPage);
internal event ChangePageHandler GoToPage;
public LoginUserControl()
{...}
//Methods for login
.....
internal void LoginOK()
{
if(this.GoToPage != null)
GoToPage(ShellWindow.PagesTypes.Home);
}
}
You can build a good dynamic using this method changing usercontrols, simulating diferent windows.
Hope this gives you some ideas.
MVVMing your child windows actually can be kind of easy, especially if you decide that a tabbed interface is OK. Your outer window's view model simply has a collection of ChildWindowViewModel. You create a new tab just by creating the new view model, asking the outer window to add it to it's collection, and WPF's DataTemplate awesomeness will take care of the proper display. You'll have to do some fiddling to get tab 'close' operations working the way you want. It's kind of a pain but doable.
If you really want to do MDI, there's nothing built into WPF for it (I think Microsoft has decided that it is a bad UI pattern now?), but there may be 3rd party controls out there for it. Any good one will still mirror this solution where their MDI container control will bind to your list of child window view models.

What is the recommended way to open a new window using MVVM in WPF

Hello everyone and thanks in advance for your time.
I'm currently learning MVVM using WPF for a small Biz App that I'm writing. I have read a lot of articles about the MVVM pattern and found that one of the key areas is to decouple the ViewModel from the View as much as possible.
I want to open a new Window in my app but I'm not sure if I should open it from the ViewModel using an ICommand or directly from the view using a standard event. Someone I work with suggested that that I should use commands, but then I thought that this would mean having a reference to a View in my ViewModel, which according to what I understand is precisely what the MVVM pattern focuses on avoiding.
My understanding is that if a window will open for navigation purposes only and the process of opening that new windows has no effect on the Model, then I should keep all of this on the view using standard events.
I know in sw development everything "depends", but guess my question is there a "right"/standard way of doing this?
Best regards,
Daniel
Yes, VMs should communicate with Views utilizing the Events that Views can subscribe to...
In VM:
public event EventHandler<NotificationEventArgs<string>> DisplayOptionsNotice;
In View:
private readonly MainViewModel mvm;
...
mvm = DataContext as MainViewModel;
mvm.DisplayOptionsNotice += DisplayOptionsWindow;
...
private void DisplayOptionsWindow(object sender, NotificationEventArgs<string> e)
{
...
optionsWindow = new OptionsWindow { Owner = this };
optionsWindow.ShowDialog();
...
}
but then I thought that this would mean having a reference to a View in my ViewModel, which according to what I understand is precisely what the MVVM pattern focuses on avoiding.
In general, the way this is handled is via some form of inversion of control. Most MVVM frameworks will provide a service of some form to open a window, and use a Service Locator or Dependency Injection to provide the service to the ViewModel.
This allows your ViewModel to stay decoupled from the specific view rendering framework - you'd pass the service the new VM and say "Show this VM in a window", and that code would be platform specific.
As Reed said Service locator or DI will do the work and wont breake the MVVM pattern.
from my experience you will have to do three things:
First check about the Service Locator or Di see what more friendly for you and implement it.
Second start making the interface of IWindow\IWindowDialog that your view (windows\ Messagebox - if you like) will implement for example.
the last thing is to implement the windows\ messages.
it will take time to do it from scratch (I did it) but if you will focus one thing at a time.
you cut the time in half.
Good luck

WPF FullScreen (MDI) but not MDI

I am redesigning my WinForms application using WPF, I was only 2 weeks in to the project and quickly learn't that many of the controls I needed would require custom controls while WPF allows me to design these easily.
So far I have a MainWindow.xaml, Login.xaml and Menu.xaml,
The idea is to display the login, upon verification show the menu then if that closes back to login inside the main window which would be full screen.
To get the functionality working I simply created the login and menu forms with the WindowStyle="none" and centered it to the screen, this obviously doesn't work because there is still a form but not linked to the main form.
In winforms I used MDI but reading this forum and looking at question MDI is frowned on, I looked at tab controls. So far I can find tutorials on using 1 form to display it but can not find a suitable tutorial for going login>menu>login
I don't want to be spoonfed, this project is just a practice project to try and get to grips with WPF but there are a lot of questions relating to the subject and everyone handles it differently it seams.
Thanks
Without creating an overly complex answer, and without including concepts that are obviously new to you such as DelegateCommand(s) or WindowManager(s), this is a bare bones example of a Fullscreen application showing many different "sub windows" (which are not windows per se, but rather UserControls)
MainWindow:
<Window x:Class="FullScreenAppSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowState="Maximized"
WindowStyle="None">
</Window>
Code Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ShowLogin()
{
var loginview = new LoginView();
this.Content = loginview;
}
private void ShowMenu()
{
var menu = new MenuView();
this.Content = menu;
}
}
LoginView:
<UserControl x:Class="FullScreenAppSample.Login.LoginView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- your login screen UI here -->
</UserControl>
MenuView:
<UserControl x:Class="FullScreenAppSample.Menu.MenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- your Menu UI here -->
</UserControl>
This is what could be called a "View First" approach, where the View dictates the "flow" of the application by taking the responsibility of instantiating other views and making them visible.
That being said, I'll take a minute to address your assertion that
everyone handles it differently
Yes. The mainstream approach to creating WPF applications is something called MVVM, which was conceived as a WPF-specific version of Martin Fowler's Presentation Model. There are, however, many interpretations and many different versions of MVVM out there, together with many MVVM Frameworks, such as MVVM Light, Caliburn.Micro, and Microsoft's Prism (amongst many others).
Each of these frameworks provide the basic tooling (base classes, helper classes, services, abstractions, event aggregators and whatnot) to ease the development of large-scale, complex WPF applications.
Bottom line: there is not a definitive "right way" to handle things like View and ViewModel instantiantion / management in WPF, that will depend on your choice of MVVM Framework and the specifics of your project, such as need for testability.
I, personally, have taken various parts and components (and concepts, too) from several different frameworks and composed my own, ViewModel-first MVVM approach. I would recommend that you take some time to analyze your project requirements and consider whether using any of these.
Instead of thinking in terms of "forms" and "windows" think of how you might design this application as if it were a web application. The login "screen" can simply be a user control laid on top of everything else that prevents the user from interacting with any of the controls below while it is displayed.
Also don't reference controls within each other directly. Instead add events to each of your user controls and bind them to the appropriate methods in other controls in your MainWindow.

Have object send message to MainPage

I have a class Target and a static property, in another class, called points. Each time the user hits a target, I want to increase the points. The reason I put points in a different static class is so that each Target object can access it.
The problem is that the textblock displaying the points exists in the MainPage and not in each Target object. Since I can't bind my XAML to a static property, how can I make it so that each Target object can somehow let the MainPage know that it should update the points textblock? thanks for any advice
You could totally apply the MVVM pattern here. If there is a static ViewModel that is bound to the main window, then you can raise a notification each time a property changes and the Views (all tied windows that display the data) will be automatially updated (re-bound).
I would recommend checking Laurent Bugnion's MVVM Light framework. It has a lot of this plumbing done for you, so all that needs to be done from your side is to put the parts together and bind them correctly.
Some resources worth checking for your situation:
WPF Apps With The
Model-View-ViewModel Design
Pattern (still applied to
Silverlight as a methodoloogy)
Model-View-ViewModel In Silverlight
2 Apps
If you need samples, take a look here.
Are Class Target and AnotherClass.points within the same name space? If so, may be the following helps:
/* In Window class */
Window w = new Window();
/* function where Target get hit */
w = this;
/* code to update points */
w.textbox1.Text = AnotherClass.points.ToString();

Categories

Resources