I frequently see new WPF users confused about what the DataContext is, and how it is used. Hopefully, this can help clarify what the DataContext is, and how it is used.
In WPF, there are two layers to an application: the UI layer and the Data layer.
The Data layer for an application starts out as null, and you can set it using the DataContext property. All UI objects will inherit their DataContext from their parent unless you specify otherwise.
When using the Model-View-ViewModel (MVVM) Design Pattern, the DataContext (Data Layer) is your application, while UI objects, like Buttons, Labels, DataGrids, and even Windows, are all just user-friendly items that allow a user to easily interact with the DataContext, which is your actual application and is typically comprised of ViewModels and Models.
Whenever you do a basic binding in WPF, you are binding to the DataContext.
For example, when you write
class="xml plain" style="font-stretch: normal; font-size: 1em !important; line-height: 1.1em !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; direction: ltr !important; box-shadow: none !important; display: inline !important; background: none !important;"><
Label
Name
=
"myLabel"
Content
=
"{Binding Path=Name}"
/>
you are binding to myLabel.DataContext.Name, and not to myLabel.Name.
Other binding properties, such as ElementName or RelativeSource, can be used to tell the binding to lookup the property in something other than the current DataContext.
Lets start with a regular Window. Without setting the DataContext, the window still displays but there is no data behind it.
<
Window
x:Name
=
"MyWindow"
...>
...
</
Window
>
Now suppose we set the DataContext to an object of type ClassA in the code-behind when this Window initializes:
public
partial
class
MyWindow: Window
{
public
MyWindow()
{
InitializeComponent();
this
.DataContext =
new
ClassA();
}
}
Now the data layer behind that the Window is an object of type ClassA.
If ClassA has a property called Name, I could add a Label to the window and bind it to Name property of the DataContext, and whatever value is stored in ClassA.Name would get displayed.
<
Window
x:Name
=
"MyWindow"
...>
<
Label
Content
=
"{Binding Name}"
/>
</
Window
>
Now, suppose ClassA has a property called ClassB, and both classes have a property called Name. Here is a block of XAML which illustrates how the DataContext works. It also includes an example of how a control would refer to a property not in its own DataContext.
<!-- DataContext set to ClassA in initialization code -->
<
Window
x:Name
=
"MyWindow"
>
<!-- DataContext here is not specified, so it's inherited
from its parent's DataContext, which is ClassA -->
<
StackPanel
>
<!-- DataContext inherited from parent, which is
ClassA, so this will display ClassA.Name -->
<
Label
Content
=
"{Binding Name}"
/>
<!-- DataContext is still ClassA, however we are
setting it to ClassA.ClassB with a binding -->
<
StackPanel
DataContext
=
"{Binding ClassB}"
>
<!-- DataContext inherited from parent, which is
ClassB, so this will display ClassB.Name -->
<
Label
Content
=
"{Binding Name}"
/>
<!-- DataContext is still ClassB, but we are
binding to the Window's DataContext.Name,
which is ClassA.Name -->
<
Label
Content="{Binding
ElementName
=
MyWindow
,
Path
=
DataContext
.Name}" />
</
StackPanel
>
<!-- We've left the StackPanel with its DataContext
bound to ClassB, so this Label's DataContext
is ClassA (inherited from parent StackPanel),
and we are binding to ClassA.ClassB.Name -->
<
Label
Content
=
"{Binding ClassB.Name}"
/>
</
StackPanel
>
</
Window
>
As you can see, all the basic bindings look for their value in the data layer (DataContext) of the UI object
So to summarize, WPF applications have two layers: the UI layer and the Data layer. The data layer for an application starts out as null, and can be set using the DataContext property. UI objects without a DataContext set will inherit their data layer from their parent object. Bindings are used to look up values in the data layer, and display them in the UI layer.
When using the MVVM design pattern, the data layer is your application, while the UI layer just provides a user-friendly way to access the Data layer.
I frequently see new WPF users confused about what the DataContext is, and how it is used. Hopefully, this can help clarify what the DataContext is, and how it is used.
In WPF, there are two layers to an application: the UI layer and the Data layer.
The Data layer for an application starts out as null, and you can set it using the DataContext property. All UI objects will inherit their DataContext from their parent unless you specify otherwise.
When using the Model-View-ViewModel (MVVM) Design Pattern, the DataContext (Data Layer) is your application, while UI objects, like Buttons, Labels, DataGrids, and even Windows, are all just user-friendly items that allow a user to easily interact with the DataContext, which is your actual application and is typically comprised of ViewModels and Models.
Whenever you do a basic binding in WPF, you are binding to the DataContext.
For example, when you write
<
Label
Name
=
"myLabel"
Content
=
"{Binding Path=Name}"
/>
you are binding to myLabel.DataContext.Name, and not to myLabel.Name.
Other binding properties, such as ElementName or RelativeSource, can be used to tell the binding to lookup the property in something other than the current DataContext.
Lets start with a regular Window. Without setting the DataContext, the window still displays but there is no data behind it.
<
Window
x:Name
=
"MyWindow"
...>
...
</
Window
>
Now suppose we set the DataContext to an object of type ClassA in the code-behind when this Window initializes:
public
partial
class
MyWindow: Window
{
public
MyWindow()
{
InitializeComponent();
this
.DataContext =
new
ClassA();
}
}
Now the data layer behind that the Window is an object of type ClassA.
If ClassA has a property called Name, I could add a Label to the window and bind it to Name property of the DataContext, and whatever value is stored in ClassA.Name would get displayed.
<
Window
x:Name
=
"MyWindow"
...>
<
Label
Content
=
"{Binding Name}"
/>
</
Window
>
Now, suppose ClassA has a property called ClassB, and both classes have a property called Name. Here is a block of XAML which illustrates how the DataContext works. It also includes an example of how a control would refer to a property not in its own DataContext.
<!-- DataContext set to ClassA in initialization code -->
<
Window
x:Name
=
"MyWindow"
>
<!-- DataContext here is not specified, so it's inherited
from its parent's DataContext, which is ClassA -->
<
StackPanel
>
<!-- DataContext inherited from parent, which is
ClassA, so this will display ClassA.Name -->
<
Label
Content
=
"{Binding Name}"
/>
<!-- DataContext is still ClassA, however we are
setting it to ClassA.ClassB with a binding -->
<
StackPanel
DataContext
=
"{Binding ClassB}"
>
<!-- DataContext inherited from parent, which is
ClassB, so this will display ClassB.Name -->
<
Label
Content
=
"{Binding Name}"
/>
<!-- DataContext is still ClassB, but we are
binding to the Window's DataContext.Name,
which is ClassA.Name -->
<
Label
Content="{Binding
ElementName
=
MyWindow
,
Path
=
DataContext
.Name}" />
</
StackPanel
>
<!-- We've left the StackPanel with its DataContext
bound to ClassB, so this Label's DataContext
is ClassA (inherited from parent StackPanel),
and we are binding to ClassA.ClassB.Name -->
<
Label
Content
=
"{Binding ClassB.Name}"
/>
</
StackPanel
>
</
Window
>
As you can see, all the basic bindings look for their value in the data layer (DataContext) of the UI object
So to summarize, WPF applications have two layers: the UI layer and the Data layer. The data layer for an application starts out as null, and can be set using the DataContext property. UI objects without a DataContext set will inherit their data layer from their parent object. Bindings are used to look up values in the data layer, and display them in the UI layer.
When using the MVVM design pattern, the data layer is your application, while the UI layer just provides a user-friendly way to access the Data layer.