How to define DataContext in XAML using StaticResource
Solution 1
If to avoid complicating the question with Entities Framework and MSSQL NorthWind database, then the good illustration is provided in Example2 sample code of codeproject "WPF/MVVM Quick Start Tutorial"
For your XAML you should change the beginning of it to:
<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.DataContext>
<vm:bNorthWind />
</Window.DataContext>
<Grid>
<!---Couldnt check your code due to dependencies on
EF and MSSQL NorthWind database
See the reference for working illustration sample:
http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial
-->
</Grid>
</Window>
Another variation of this approach can be seen in "What is the advantage of setting DataContext in code instead of XAML?", the part:
<StackPanel.DataContext>
<local:CustomerViewModel />
</StackPanel.DataContext>
Migrating DataContext
definition from codebehind to XAML is unrelated to the usage of either StaticResource
or DynamicResource
. See: What's the difference between StaticResource and DynamicResource in WPF? probably better addressed in codeproject WPF: StaticResource vs. DynamicResource
Related, helpful and further reading:
- How to get rid of StackOverflow Exception in DataContext InitializeComponent?
- Why does binding the MainWindow datacontext in XAML fail to act the same as binding in the codebehind with this.datacontext=this?
Solution 2
I prefer to set the key as a static string - WPF has enough magic strings without cornering yourself into a refactoring corner if you can easily avoid it.
in App.xaml
xmlns:viewModels="clr-namespace:MyAppNamespace.ViewModels"
xmlns:local="clr-namespace:tvCADdesktop"
x:Name="App"
...
<viewModels:ApplicationViewModel x:Key= "{x:Static local:App.MainVmResourceKey}"/>
in App.xaml.cs
public static readonly string MainVmResourceKey = "MainVm";
in my various Control.xaml
<UserControl.DataContext>
<Binding>
<Binding.Source>
<StaticResource ResourceKey="{x:Static app:App.MainVmResourceKey}" />
</Binding.Source>
</Binding>
</UserControl.DataContext>
note the UserControl
part is whatever type you want to apply the ViewModel to.
Related videos on Youtube
Jim Thomas
Updated on December 05, 2020Comments
-
Jim Thomas over 3 years
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#) but want to learn how to do in XAML. I have tried all of the examples I can find 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?
C#
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>
-
Zev Spitz over 4 yearsIs there any benefit to using a static resource vs. setting
Window.DataContext
directly? If not, then this answer suggests setting it directly.