Create a view model class.
Instantiate the view model class within the xaml of the view by creating it inside the DataContext
property.
Implement a method to load the data in your view model, e.g. LoadData
.
Set up the view, so that this method is called when the view loads.
You can do that by implementing the Loaded
event in an event handler of the view, or alternatively you can you an interaction trigger in your view and link it to the method in the view model.
View (xaml):
<Window x:Class="MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test"
xmlns:viewModel="clr-namespace:ViewModels" Loaded="Window_Loaded">
<Window.DataContext>
<viewModel:ExampleViewModel/>
</Window.DataContext>
View (code behind):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
((ExampleViewModel)this.DataContext).LoadData();
}
If you do not like setting up the Loaded
event in the code behind, you can also do it in xaml (references to "Microsoft.Expression.Interactions" and "System.Windows.Interactivity" are needed):
<Window x:Class="MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test"
xmlns:viewModel="clr-namespace:ViewModels"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
>
<Window.DataContext>
<viewModel:ExampleViewModel/>
</Window.DataContext>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="LoadData"/>
</i:EventTrigger>
</i:Interaction.Triggers>
In each case, you call the LoadData
method in the ViewModel.
Here, you should make a call to a separate class which provides the data.
This class is usually called repository.
public class ExampleViewModel
{
/// <summary>
/// Constructor.
/// </summary>
public ExampleViewModel()
{
// Do NOT do complex stuff here
}
public void LoadData()
{
// Make a call to the repository class here
// to set properties of your view model
}
If the method in the repository is an async method, you can make the LoadData
method async too, but this is not needed in each case.
Generally I would not load data in the constructor of the view model.
In the example above the (parameter less) constructor of the view model is called when the designer shows your view. Doing complex things here can cause errors in the designer when showing your view (for the same reason I would not make complex things in the views constructor).
In some scenarios code in the view models constructor can even cause issues at runtime, when the view models constructors executes, set properties of the view model which are bound to elements in the view, while the view object is not completely finished creating.