Navigate from one view to another in WPF - wpf

I want to navigate from one view to another view in WPF using MVVM. How can I do this? Please let me know the procedure.
Thanks,
Prashant

You would simply create your new view, assign it's view model, and then Navigate to it:
this.NavigationService.Navigate(new SomeOtherView { ViewModel = someViewModel }, null);

'Navigate' is a bit vague, but when I have a 'screen-based' application with content hosted in a particular section of a larger window (with say button-based navigation controls and status surrounding the content area), I like using a MainViewModel, with an ActiveScreen property of type Object and a ContentPresenter bound to ActiveScreen. I'll define DataTemplates that bind the various ViewModel instances to the appropriate View control and simply instantiate or select from different ViewModels for the ActiveScreen. The binding system takes care of the actual instantiation of the View instances.

Related

How to bind to a method on ViewModel with data from View

I currently have one view with 3 fairly simplistic view models. For the sake of this discussion, we will focus on 2 of the three view models.
The View is a User Management user control. It contains a DataGrid that has its ItemsSource binding set to a UserListViewModel. This view model simply displays user information in the data grid.
The User Management View also contains some other controls, such as buttons for adding new users and removing users. Those buttons are currently bound to a second view model called UserManagementViewModel. For example, the Remove button will successfully call the RemoveUser method on the UserManagementViewModel.
My question is, via XAML (as I hate code-behind), how can I pass the SelectedItem property of the DataGrid (bound to UserListViewModel) into the RemoveUser method call on the UserManagementViewModel? I realize that, in the MVVM design pattern, my view model can't look into the view to retrieve the information necessary, so there must be a way via binding to pass that information into the method.
XAML code examples (or links that show how) to perform similar functionality would be appreciated. Thanks for any help!
you can simply use a commandparameter
<Button Command="{Binding RemoveCommand} CommandParameter="{Binding Elementname=gridUser, Path=SelectedItem}" />
or your UserManagementViewModel have access to the UserListViewModel then you need a command without commandparameter and simply use the SelectedUser property of your UserListViewModel instance
public void ExecuteRemove()
{
var userToRemove = this._myUserListViewModelinstance.SelectedUser;
...
}
I believe what you seek is commanding with a command target bound to the datagrid's selecteditem where one can route such information from the datagrid; say when a button is pressed.
See Commanding Overview on MSDN

DataTemplate for View made up of different Views

In a Windows 8 style app I have a View (or page) which is made up of several other Sub-Views.
Each of these has an associated ViewModel and they are defined and bounded via the MVVM Light ViewModelLocator
I then have a View2 which is made up of other Sub-Views which, again, are defined and bounded via the MVVM Light ViewModelLocator
What I want to do is to place instances of the View and View2 controls into a List on a MasterViewModel and then bind this list to a GridView on a MasterView file.
Each of the instances of View and View2 should render as they do if you were to create a single instance without placing it into a list.
What I have tried to do is create a List of Pages (as all views are instances of this type) and bind the GridView to this, but when I run the app the GridView appears empty.
I have seen an examples that use a DataTemplateSelector (http://www.wiredprairie.us/blog/index.php/archives/1705) and apply a DataTemplate to each of the items in the MasterView list.
I understand what this does, but what I don’t understand is how to create a DataTemplate for a View that is made up of other Views.
I’m sure I am overlooking something and / or just making this harder than it needs to be!
Thank you for any help :)
Normally in this case, you would be binding a list to a set of ViewModels, not views, and the data template selector (or ValueConverter depending on your flavour) would select and instantiate a view suited to the view model.
So if ViewA uses ViewModelA : ISubViewViewModel, and ViewB uses ViewModelB : ISubViewModel then your main ViewModel would contain a List<ISubViewModel> which has a set of ViewModelA & ViewModelB within it. The main view's ListBox is bound to the List<ISubViewModel> and the data template selector / ValueConverter resolves ViewA for ViewModelA's and ViewB for ViewModelB's.
Hope that makes sense, it's about as hard to describe the solution as it probably was to describe the problem. :)

Custom control, View Model and dependency properties

I'm creating custom control and because I need to do lot's of binding inside a style/template it makes perfect sense to go with MVVM. Where do I declare dependency properties then?
Do they stay in control class? How do I link them to VM?
See my answer to your other question about custom controls and view models. Here's the short version:
Custom controls shouldn't have view models.Don't set the data context of your own control. That's reserved for the consumer.All of your dependency properties should be declared in your MyCustomControl.cs file.Use TemplateBinding in your genric.xaml because it's more efficient that Binding.
To put it another way, what's the view model for a Border or a Button? Answer: they don't have one because they're just controls. UserControls have view models, but controls just present and interact with the data which you give them (where? In your UserControl). Custom control development is probably the hardest thing for a seasoned MVVM developer: your reflex is to make a view model, but that reflex is unfortunately wrong. I know because I've made this mistake myself.
Dependency Properties could be delared in the Control they are belongs to.
When following MVVM in WPF/Silverlight the common approach is to set ViewModel as DataContext of the appropriate View. So you would be able to link custom Dependency Properties to the ViewModel properties using Bindings in XAML.
Let's assume you already set ViewMosel to DataContext of the View:
var view = new UserView
{
DataContext = new UserViewModel { Name = "Custom Name" }
};
public class UserViewModel
{
string Name { get; set; }
}
UserView.xaml:
<TextBlock Text="{Binding Name}" />
When creating a custom control, the control itself is a view model. Declare dependency properties on it to expose bindings that users of the custom control can leverage. For example if you have a timeline control, you might have properties like StartDate and EndDate on the control exposed as dependency properties. Your Controls Default Template would make template bindings to the dependency properties. A consumer of your control might then have a project timeline viewmodel that he binds to the properties on the control.
The primary purpose of a custom control is to provide behavior and a default look and feel for that behavior which is easy to override (by providing a new template). Hope this helps.

Can MVVM Usercontrols have property defined in codebehind?

I have a WPF user control ...which is in MVVM. The user control(which contains a listview) need data from the page (where it is included). I have to set a property to get this data input. Will this comply with MVVM...if not, what is the way for the same?
I'm afraid this won't be correct in MVVM design pattern. try to stick to your view model to define properties. Why don't you consider moving that property to control's vm?
Use an ObservableCollection rather.
ObservableCollection<myModel> myOC = new ObservableCollection<myModel>();
where myModel is a class that has to be constructed transforming your columns in the DataTable to Properties.
In your MainViewModel, loop through the DataReader and create myOC out of it.
Now bind myOC to a ListView in your page.
The DataTemplate of ListView should be a view(UserControl) drawing data from a ViewModel constructed out of myModel
But your UserControl has the entire ListView inside. If that is on purpose, then let me know the entire design to give a better idea.

How do I databind to a ViewModel in Expression Blend?

In WPF and Silverlight you can make a view model object and set it into the DataContext of a control when the control is constructed at runtime. You can then bind properties of the visual object to properties in your DataContext.
One way to set the binding is to type the binding directly into the tag:
<TextBox Text="{Binding Path=Description}"/>
And this will bind the textbox to the Description property in the view model.
The problem with typing in the binding is that you may make a typing mistake. (And you will almost certainly make a mistake if you have hundreds of bindings to make.)
In Expression Blend there is a little white dot beside the Text property in the Properties window. This brings up a menu from which you can Create Data Binding.
How can I get my view model properties to show in the Create Data Binding dialog so that I can select them.
Will the configuration of data binding in Blend interfere with setting my view model into the DataContext at runtime?
One technique is to include the VM as a resource in your view:
<UserControl>
<UserControl.Resources>
<local:YourViewModel x:Key="ViewModel"/>
</UserControl.Resources>
</UserControl>
You can then reference that as DataContext="{StaticResource ViewModel}" elsewhere.
Can't say I like it, but I can't say I like any of the view-first idiosynchrasies that Blend imposes on your design.
I experimented with Blend to find the drag and drop approach to data binding which still lets you override your view model in code easily.
First make your view model object which implements INotifyPropertyChanged and raises the notify event in the setters. The view models can be hierarchical. For example you could have an ObservableCollection within your main view model.
In Blend open up your page or control and go to the data tab.
On the right open the menu under the "Add live data source" icon.
Pick "Define new object data source"
Select your top level view model class and confirm the dialog
In my experiments I found that it was important to bind the data source to where I wanted it first or else Blend might make a less than optimal configuration if I didn't do the next step first.
Open the Objects and Timeline window in Blend
Select the root object, for example UserControl
Open Properties and verify that the root object is selected
Find DataContext and click the square to open the menu and select DataBinding
Select the data source that was just previously created
Now that the data source has been created data binding is very easy.
put some controls on the page
open the Data window
from the DataSource for your view model drag properties onto the controls to create the bindings or set the binding from the Properties window.
Now you can create you live view model object in the constructor of the control
public MainPage()
{
// Required to initialize variables
InitializeComponent();
mVm = new MyViewModel();
this.DataContext = mVm;
}
private MyViewModel mVm;
Add any initialization to retrieve data and you are ready to go.
I have a screen cast on my blog Blendable MVVM : Introduction and Databinding which shows setting this up for Siverlight.
Essentially you create the ViewModel as the DataContext of the UserControl using the "New Object Initialiser" and then using the "Explicit Data Context" tab of the Binding dialog for the controls themselves.
Hope this helps.

Resources