MVVM View-First Approach How Change View - wpf

Does anybody have an idea how to change screens (views) in a MVVM View-First-Approach (The view instantiates the ViewModel:
DataContext="{Binding Source={StaticResource VMLocator},
Path=Find[EntranceViewModel]}"
)
For example:
In my MainWindow (Shell) I show a entrance view with a Button "GoToBeach".
<Window>
<DockPanel>
<TextBox DockPanel.Dock="Top" Text="{Binding Title}" />
<view.EntranceView DockPanel.Dock="Top" />
</DockPanel>
</Window>
When the button is clicked I want to get rid of the "EntranceView" and show the "BeachView".
I am really curious if somebody knows a way to keep the View-First Approach and change the screen (view) to the "BeachView".
I know there are several ways to implement it in a ViewModel-First Approach, but that is not the question.
Perhabs I missed something in my mvvm investigation and can't see the wood for the trees... otherwise i am
hoping for a inspiring discussion.

One possibility would be to have all views in the (MainWindow(Shell) and using Triggers for their visibility. But having a lot of different screens (views) all declared in the MainWindow doesnt feel right for me...
This question came up while reading this nice way of using MEF with MVVM I found on John Papas Blog: Simple ViewModel Locator for MVVM: The Patients Have Left the Asylum . But as nice as this marriage of view and viewmodel is, it seems like there is no way to change screens that satisfies me. :)
So in my opinion if you have a lot of screens(views) you better use a ViewModel-First-Approach...

This looks like it might help:
Creating a ViewModel : do it before or after model data is available?
Failing that, how about creating the ViewModel once only at startup, and assigning it to each View window as it's created (rather than creating a new ViewModel each time). Then just close the first View and open up a new View as required, reassigning the single ViewModel instance.

You may want to look at Prism (i.e. the composite application library). Prism facilitates navigation between views via the region manager. This might be overkill for your application and can take a while to get your head around. Prism also allows you to develop using the MVVM pattern as well.
You can find more information about prism and prism navigation in the Prism documentation.

Related

Get XAML View element without breaking MVVM

I need a reference to a Visual (one element of a XAML View Window) in my ViewModel to work with VisualTreeHelper methods like VisualTreeHelper.GetDescendantBounds(Visual reference) but I do not want to break MVVM rules and just name the viewport3d and provide it as a reference when instancing my ViewModel.
Currently I am binding the geometry as content like this to my ViewModel:
<Viewport3D>
<ModelVisual3D Content="{Binding SceneContent.Content}"/>
</Viewport3D>
But I do not see the MVVM possibility to get the containing ModelVisual3D into my ViewModel. Is there a standard (may be data-binding) approach to this in MVVM applications?
Using MVVM, we don't 'get view elements'. If you need to do something with a UI element, then that has nothing to do with MVVM. If you need to use the VisualTreeHelper.GetDescendantBounds method, then once again, that has absolutely nothing to do with MVVM... why do so many people claim to use MVVM, but know nothing about it?
Therefore, your question is invalid. It is entirely appropriate in situations like these for you to use the code behind. In fact, this is a perfect example of when we should use the code behind when following the MVVM methodology. If it is only UI related, then it has no purpose being in a view model, so simply don't put it there.
Please read the answer to the What are MVVM limitations? question to get some further insight into MVVM.

MVVM Light Multiple Data Contexts

I am new to MVMM Light toolkit (note, I'm using Light on .NET 3.5). So far I am really starting to like the pattern save for two challenges.
I'd like to have reusable XAML templates for certain types of pages in my application. Think of a movie ticket kiosk. Main content in the center but almost always a button somewhere on the screen to cancel or go back. I'd like to have reusable grid(s) where when I create a new page I basically import that grid layout and don't have to worry about the common bits and can just focus on my part. Doing a little research I feel like <ContentPresenter> might be the way to go here but it's still foreign to me.
Assumign I succeed in my first challenge, I would think the data context for those common items (say a Cancel button) would be somewhere else other than that page's ViewModel to avoid a bunch of duplication of code. Is that best approach to take the individual controls and reference a different view model from the XAML? Something like...
<Button ... DataContext={Binding CommonStuffVM, Source={StaticResource Locator}} />
You can use Templates or DataTemplates to create a reusable template defining how an object should look.
For example,
<DataTemplate DataType="{x:Type local:MovieTicket}">
<!-- Write the XAML for your Movie Ticket -->
</DataTemplate>
You can give your DataTemplate an x:Key to reference it specifically in an ItemTemplate or ContentTemplate, or leave it out so it will be used anytime WPF tries to draw a MovieTicket object
<ItemsControl ItemsSource="{Binding MovieTickets}" />
<ContentControl Content="{Binding SelectedMovieTicket}" />
For your second question, I think this would be a bad idea for individual controls, although its a common practice for complete sections of the program.
When using MVVM, your ViewModels are your application, not your UI.
If your window should display a list of Movies for the user to edit, and allow the user to Save or Cancel their changes, then your ViewModel should contain an ObservableCollection<Movie> and contain an ICommand SaveCommand and ICommand CancelCommand
You really want your View to only reflect your ViewModels, and not have them pulling the data they need from all over the ViewModel hierarchy.
Based on your question, you may be interested in a blog article I have about Navigation with MVVM which uses code very similar to what you're asking about. It shows how to change the UI using implicit DataTemplates, and contains a complete code sample that you can download and look at to get a better idea of the MVVM architecture.

How to leverage designer when using a ViewModel first approach and composition

I have some xaml like:
<ContentControl x:Name="MyContent" />
and then on my ViewModel there is, of course, a MyContent property which references a ViewModel. Then Caliburn does its compositional magic.
This is great, but in design time I can't see the composition. I see 'most' people raving about the view model first approach, but I'm a little baffled as to whether there's a way to leverage the designer when doing this that I haven't yet realized or do all the vm first people just live with the fact that they have to run the application to see what it's going to look like?

General Design Question about data binding in WPF

I'm starting to use Binding in my WPF project and I'm actually confused about few things on the presentation side (XAML).
So I want to populate a TreeView with a List of Categories. I know how to write the right HierarchicalDataTemplate for my List of Category instances.
<HierarchicalDataTemplate ItemsSource="{Binding Path=ChildrenCategories}" DataType="{x:Type src:Category}">
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</HierarchicalDataTemplate>
But what now I don't know is from where to get the list. I have here 2 solutions :
I got a Library Singleton class
which return me the right
arborescence, then I need to use an
ObjectDataProvider in my xaml which
would call the
Library.Instance.Categories method. (Which means that the controller has to be completely separated from the UI).
I got a Property ListCategories
in my page interactionLogic
(OpenUnit.xaml.cs), and bind the
tree with it.
I'm not sure about the purpose of the xaml.cs files, what are they made for? Is it normally used to store the properties (and act as a controller) or simply to have a back-end for the UI (for example get values from the UI?)?
In case the xaml.cs file is used as a controller, how do I bind my data to it, I've tried many solutions without success,my only success was with the use of static binding.
I would appreciate any comment or recommandation about UI and Logic Binding in WPF, hopefully I will get less confused.
Thanks in advance,
Boris
After reading this great article, I got a little bit less confused :
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
The article is about the Model View ViewController pattern, and how WPF integrates it. So it seems that xaml.cs files should be used as the ViewController here, and should hold the properties.
It actually make sense since it's not a good practice to mix the View and the Data, we want the designers should have a completely independant work to do.
Also for the solution 2) it is possible if you set the data context to the current file.

Manage complex UI with MVVM

My question is actually about starting an application with MVVM :
My main screen will host many screens. I understand that they will be UserControls.
But i don't see where i instantiate then when i want, when i show them and when i hide them ?
The logic is not clear to me. Can someone explain me or point me to a simple and clear example ?
Thanks
John
Imagine that you have got a MainViewModel which binds to the main screen.Let the MainViewModel be a singleton class and it has a 'CurrentViewModel' property (INotifypropertyChanged implemented) in it. Now you can instantiate any particular ViewModel (based on a Command/Click) and assign the instance as below
MainViewModel.Instance.CurrentViewModel = new SomeViewModel();
So now your main screen XAML will have
<Window>
<ContentControl Content="{Binding CurrentViewModel,Source={x:static vm:MainViewModel.Instance}}"
</Window>
You need to define proper DataTemplates for each ViewModels (View to ViewModel Mapping). That will look like
<DataTemplate DataType="{x:Type vm:SomeViewModel}">
<view:SomeView/>
</DataTemplate>
Here SomeView is the UserControl corresponds to the SomeVieModel.
Hope this explains the MVVM architecture very briefly
You could use an existing application framework to help manage this rather than doing it yourself. Caliburn in particular addresses this problem with its IPresenter Component Model. I'm sure there are others out there too.

Resources