Solved

How to define DataContext in XAML using StaticResource

Posted on 2010-08-19
5
5,458 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
  • 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 500 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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

707 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now