πŸ“œ ⬆️ ⬇️

WPF Binding: How to decide what to use: DataContext or Source?

Hello! Not long ago, I wrote my first translation of a post about WPF Binding from the Beatriz Cost blog . It was adopted quite well, so I made a decision regularly, about once a week (sometimes, perhaps more often) to translate one post from this blog. This time, I decided to translate a small (no time for large) article, which tells about the situations in which it is better to use the DataContext, and in which the Source property.

To begin with, it should be said that the DataContext property is one of the most fundamental concepts in Data Binding.

Any Binding needs to get information from somewhere, and there are several ways to tell it the source of the data. In this post, I will tell you how to set the Source property directly through the Binding object, and about the inheritance of the DataContext from the nearest parent in the element tree. Also there are two more ways. This is setting the ElementName and RelativeSource properties in the Binding, but I will leave them for the following posts.

For example, let's imagine that we have the following data source (the GreekGod class is declared in the code):
< Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  1. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  2. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  3. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  4. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  5. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  6. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  7. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  8. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
  9. < Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .
< Window.Resources > < local:GreekGod Name =” Zeus ” Description =” Supreme God of the Olympians ” RomanName =” Jupiter ” x:Key =” zeus ” /> < local:GreekGod Name =” Poseidon ” Description =” God of the sea , earthquakes and horses ” RomanName =” Neptune ” x:Key =” poseidon ” /> </ Window.Resources > < StackPanel DataContext =”{ StaticResource poseidon }” > < TextBlock TextContent =”{ Binding Source ={ StaticResource zeus }, Path = Name }” /> < TextBlock TextContent =”{ Binding Path = Description }” /> < TextBlock TextContent =”{ Binding Path = RomanName }” /> </ StackPanel > * This source code was highlighted with Source Code Highlighter .

The first TextBlock inherits the DataContext from its ancestor, StackPanel, and it also has the Source property in its Binding. In this situation, the Source property takes precedence. Because the TextBlock retrieves data from the Name property of an object with the β€œzeus” key, it will display the word β€œZeus”.
')
For the second TextBlock, the Source property is not set directly in the Binding object. Therefore, it inherits the DataContext from the parent StackPanel. As you might have guessed, this will indicate the Description property of the resource with the key β€œposeidon” and the inscription β€œGod of the sea, earthquakes and horses” is displayed on the element.

With the third TextBlock, everything is the same as with the second. It will display the word "Neptune".

Most programs that use Data Binding that I've seen use DataContext much more often, which is much more complicated than Source. I recommend using the DataContext only where you need to bind more than one property from a specific source. When only one property is bound, I always use Source. The reason for this is that it is easier to debug this way - in order to understand what is happening, I would prefer to see all the information about the Binding in one place, rather than look for it in the nearest DataContext. In our small example, this is easy, but in large applications it will save you some time.

Here you can find a project for Visual Studio with the code that was used in the article.

Source: https://habr.com/ru/post/41481/


All Articles