Wednesday, 21 May 2014

Six ways to instantiate a ViewModel in MVVM

There are many ways you can attach your ViewModel to your View in WPF; here are some of the ways.

Direct reference to the ViewModel

This is the simplest method.

<UserControl xmlns:vm="clr-namespace:MyWPFUserControls">
    <UserControl.DataContext>
        <vm:MeterReaderViewModel/>
    </UserControl.DataContext>

Use a CollectionViewSource

<Window.Resources>
    <CollectionViewSource x:Key="categoryViewSource" d:DesignSource="{d:DesignInstancemy:Category, CreateList=True}" />
</Window.Resources>
<Grid DataContext="{StaticResource categoryViewSource}">
...

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        System.Windows.Data.CollectionViewSource categoryViewSource =
            ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));

        // Load is an extension method on IQueryable, defined in the System.Data.Entity namespace.
        // This method enumerates the results of the query, much like ToList but without creating a list.
        // When used with Linq to Entities this method creates the entity instances and adds to the context.
        _context.Categories.Load(); // Load is defined in the System.Data.Entity namespace.     

        // After the data is loaded call the DbSet<T>.Local property to use the DbSet<T> as a binding source.
        categoryViewSource.Source = _context.Categories.Local;      
    }

Reference

CollectionViewSource – more simple version

    <UserControl.Resources>
        <CollectionViewSource x:Key="MainDataSource"/>
    </UserControl.Resources>
    <Grid DataContext="{Binding Source={StaticResource MainDataSource}}">
 
var collectionView = (CollectionViewSource)Resources["MainDataSource"];
collectionView.Source = entitiesContext.ArCustomers;

Call a method

Note the "Class" reference on the second line.

<Window
   x:Class="U2UConsult.DockOfTheBay.DataGridSampleWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:U2UConsult.DockOfTheBay"
   xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
   Title="WPF DataGrid CRUD Sample"
   SizeToContent="WidthAndHeight"
   Icon="/DataGridSample;component/dotbay.png" >
...
<toolkit:DataGrid
   x:Name="DriversDataGrid"
   ItemsSource="{Binding Source={x:Static local:FormulaOneDriver.GetAll}}"
   RowEditEnding="DriversDataGrid_RowEditEnding"
   AutoGenerateColumns="False"
   CanUserAddRows="True"

Reference

Call a method in an ObjectDataProvider

<Window ...>

    <Window.Resources>
        <!-- create an instance of our DataProvider class -->
        <ObjectDataProvider x:Key="CustomerDataProvider"
            ObjectType="{x:Type local:CustomerDataProvider}"/>
        <!-- define the method which is invoked to obtain our data -->
        <ObjectDataProvider x:Key="Customers"
          ObjectInstance="{StaticResource CustomerDataProvider}"
          MethodName="GetCustomers"/>
    </Window.Resources>

    <DockPanel DataContext="{Binding Source={StaticResource Customers}}">
        <dg:DataGrid ItemsSource="{Binding}" Name="dataGrid"/>
    </DockPanel>
</Window>

public class CustomerDataProvider
{
    private CustomersTableAdapter adapter;

    private NorthwindDataSet dataset;

    public CustomerDataProvider()
    {
        dataset = new NorthwindDataSet();
        adapter = new CustomersTableAdapter();
        adapter.Fill(dataset.Customers);
    }

    public DataView GetCustomers()
    {
        return dataset.Customers.DefaultView;
    }
}

Reference

OnStartup

You can initialize the View and View Model by using an OnStartup() override added to App.xaml.cs. The View is bound to the View Model by setting the View Model as the data context for the View:


protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    var mainWindow = new MainWindow();
    var mainWindowViewModel = new MainWindowViewModel();
    mainWindow.DataContext = mainWindowViewModel;
    mainWindow.Show();
}

Reference
http://www.codeproject.com/Articles/182880/Using-the-Microsoft-Desktop-Stack-Part-3-Using-Ent

________________________________________________________________________________

No comments:

Post a Comment