Reputation: 2620
I usually instantiate my ViewModel in codebehind and set it as the DataContext for the Window or UserControl.
For this simple ViewModel:
public class ViewModel
{
public ObservableCollection<string> items { get; set; }
public ViewModel()
{
items = new ObservableCollection<string>();
items.Add("FirstItem");
items.Add("SecondItem");
items.Add("ThirdItem");
}
}
i am adding my local namespace and the following syntax will set the things right:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
Fine, i understand that a ViewModel object is instantiated and set as DataContext for the window, it works as expected but is there any way to access the instantiated object from code?
If i create the object in the codebehind with
ViewModel vm = new VewModel();
this.DataContext = vm;
i am able to access vm instance but with the XAML approach, how can it be reached?
I've created this small example in order to find out if there is a simple answer available.
Upvotes: 7
Views: 6360
Reputation: 1
For anyone getting here via Google about passing an instantiated ViewModel in the code-behind in to the XAML as a DataContext...
Instead of setting the DataContext directly in the code-behind, you can add the ViewModel (or whatever you need) to the Resources dictionary directly by calling
Resources.Add("ResourceKey", ResourceObjectGoHere)
After that you can access the resource by binding the DataContext of whatever control you'd like to via {StaticResource ResourceKey}. This way you don't lock the entire window into a single DataContext. :)
Upvotes: 0
Reputation: 9723
When you set the DataContext
of any element, then all of the children of said element will also have the same DataContext
.
Picture the scene:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
Here you have given the Window
a DataContext
. Now, all child elements within your window effectively have the same DataContext
.
<TextBox Text="{Binding MyProperty}" />
To get hold of the DataContext
in code-behind, you can simply reference the DataContext
of the element.
ViewModel vm = (ViewModel)this.DataContext;
The code above references the DataContext
of the Window
.
If you need to be more specific, and get the DataContext
of a specific element, then you can simply reference the element by name.
ViewModel vm = (ViewModel)elementName.DataContext;
All that aside, you should never set the DataContext
in code-behind. The MVVM design pattern likes to keep things separated, and if you start setting the DataContext
of a UserControl
for example, then things get screwed up pretty quickly.
Setting the DataContext
in XAML is the right way to go.
Upvotes: 10