Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How to define DataContext in XAML using StaticResource

Posted on 2010-08-19
5
Medium Priority
?
5,816 Views
Last Modified: 2013-12-17
I want to declare a DataContext through a static resource in XAML as a binding for the Customers in the Northwind database. I can do this easily in code (C# commented out code below) but want to learn how to do it in XAML. I have tried all of the examples I can find (including one on this site) but none of them work for me. I believe the issue is in the two XAML lines of code I have labeled [Option1] and [Option2]. Can you clarify what the syntax for this really should be?
namespace DataGridEF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            bModel1 bNorthWind = new bModel1();
            //this.DataContext = bNorthWind;
            bNorthWind.GetCustomers();
        }
    }
}

namespace DataGridEF
{
    public class bModel1
    {
        List<Customer> _Customers;
        public List<Customer> Customers
        {
            get { return _Customers; }
            set { _Customers = value; }
        }

        public void GetCustomers()
        {
            NorthwindEntities NorthWind = new NorthwindEntities();
            var CustomerQ = from cust in NorthWind.Customers select cust;
            _Customers = CustomerQ.ToList();
        }

    }
}
XAML
<Window x:Class="DataGridEF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:vm="clr-namespace:DataGridEF">

<Window.Resources>
    <vm:bModel1 x:Key="TheViewModel" />
</Window.Resources>

<Grid>
    <DataGrid AutoGenerateColumns="False" Height="195" HorizontalAlignment="Left" Margin="20,89,0,0" 
              Name="dataGrid1" ItemsSource="{Binding Path=Customers}" 
              [option1]DataContext="{StaticResource TheViewModel}"
              [option2]DataContext="{Binding Path=., Source={StaticResource TheViewModel}}"
              VerticalAlignment="Top" Width="471" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=ContactName}" />
            <DataGridTextColumn Header="Address" Binding="{Binding Path=Address}" />
            <DataGridTextColumn Header="City" Binding="{Binding Path=City}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>
</Window>

Open in new window

0
Comment
Question by:esc_toe_account
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 27

Expert Comment

by:MikeToole
ID: 33482610
>>            bModel1 bNorthWind = new bModel1();
>>            //this.DataContext = bNorthWind;

Why the introduction of a new class, bModel1?

The equivalent in XAML of     //this.DataContext = bNorthWind;    is a resource entry plus a DataContext assignment:

-   This statement essentially creates an instance of bNorthWind with TheViewModel as the key.

    <vm:bNorthWind  x:Key="TheViewModel" />

-   To set a DataContext from it assign it on an element in your xaml:

     DataContext="{StaticResource TheViewModel}"

The assignment in code-behind sets the context for the whole Window. To get a near-equivalent scope you could set the context on the Grid:

<Grid      DataContext="{StaticResource TheViewModel}"  >

0
 

Author Comment

by:esc_toe_account
ID: 33488707
Thanks for your suggestion. That was one of the variants I tried earlier and did not have success with.

Here are the two compile errors I get with the code you sugested:

Error      1      The tag 'bNorthWind' does not exist in XML namespace 'clr-namespace:DataGridEF'. Line 8 Position 10.      C:\VS\Samples\DataGridEF\DataGridEF\MainWindow.xaml      8      10      DataGridEF

Error      2      The type 'vm:bNorthWind' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.      C:\VS\Samples\DataGridEF\DataGridEF\MainWindow.xaml      8      10      DataGridEF

Not sure why it can't find bNorthWind. I tried declaring it public but that didn't make any difference.

In answer to your question 'why the new class bModel' - that is because I am prototyping a MVVM pattern and have separated out the View from the ViewModel (or Business Model: bModel)
0
 

Author Comment

by:esc_toe_account
ID: 33488744
I can't edit the original submission so here is what the new public declaration of bNorthWind looks like. But as mentioned above, didn't make the object viewable - still get the errors shown.

   
public partial class MainWindow : Window
 {
        public bModel1 bNorthWind;
        public MainWindow()
        {
            InitializeComponent();
            bNorthWind = new bModel1();
            //this.DataContext = bNorthWind;
            bNorthWind.GetCustomers();
        }

        private void SaveBtn_Click(object sender, RoutedEventArgs e)
        {

            bNorthWind.SaveChanges();
        }
    }

Open in new window

0
 
LVL 27

Accepted Solution

by:
MikeToole earned 2000 total points
ID: 33490835
When setting the DataContext in XAML there is no need for any code in the code behind.
This entry in the resources section creates a new instance of bNorthWind:
    <vm:bNorthWind  x:Key="TheViewModel" />
... but this assumes that bNorthWind is a class, your code suggests that it's actually an instance of bModel1

In the MVVM pattern the Model and ViewModel are different classes

The attached example shows a class set as datacontext
- the code behind file is completly empty

<Window x:Class="cSharpTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:cSharpTest"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <vm:MyData x:Key="ViewModel"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource ViewModel}">
        <ListBox Name="MyListBox" ItemsSource="{Binding Primes}"/>
    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace cSharpTest
{
    class MyData
    {
        public MyData()
        {
            _primes = new int[5] { 1, 3, 5, 7, 11 };
        }
        private int[] _primes;
        public  int[] Primes
        {
            get { return this._primes; }
         }
    }
}

Open in new window

0
 

Author Comment

by:esc_toe_account
ID: 33500838
Thanks Mike, your comments got it working for me. I did not realize that
    <vm:bModel1 x:Key="TheViewModel" />
was actually creating a new instance; I was expecting it to reference an existing instance! Therefore, by simply putting some code in the class constructor to fetch the data I got the datagrid to display the customer table.

I don't think I will be using this construct very much: Visual Studio designer reports it can't create the instance (I assume because the data base connection is not open) however the code runs fine.

Apparently, in order to reference an existing instance (created in C#) I would have to use a BindableStaticResource which is way more work than I want to get into, especially since a single line of C# (this.DataContext = bNorthWind;) sets the DataContext quite easily.

0

Featured Post

Enroll in September's Course of the Month

This month’s featured course covers 16 hours of training in installation, management, and deployment of VMware vSphere virtualization environments. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question