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.
User interface elements in WPF have a DataContext dependency property. That property has the aforementioned "value inheritance" feature enabled, so if you set the DataContext on an element to a Student object, the DataContext property on all of its logical descendant elements will reference that Student object too.
By setting the UserControl DataContext to itself, this overwrites the DataContext and breaks Inheritance. Instead, nest it one Element deep in the XAML, in your case, the StackPanel . Put the DataContext binding here and bind it to the UserControl .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With