Pull to refresh

WPF Binding: Как решить, что использовать: DataContext или Source?

Reading time 2 min
Views 30K
Original author: Beatriz Costa
Здравствуйте! Не так давно я написал свой первый перевод поста про WPF Binding из блога Beatriz Cost'ы. Он был принят достаточно хорошо, так что я принял решение регулярно, примерно раз в неделю (иногда, возможно, и чаще), переводить по одному посту из этого блога. В этот раз я решил перевести небольшую (на большие пока нет времени) статью, в которой рассказывается о том, в каких ситуациях лучше использовать DataContext, а в каких свойство Source.

Для начала следует сказать, что свойство DataContext — это одна из наиболее фундаментальных концепций в Data Binding'е.

Любому Binding'у нужно откуда-то получать информацию, и для того, чтобы указать ему источник данных, существует несколько способов. В этом посте я расскажу вам о том, как установить свойство Source непосредственно через объект Binding, так и о наследовании DataContext'а от ближайшего вышестоящего элемента в дереве элементов. Так же существует еще два способа. Это установка свойств ElementName и RelativeSource в Binding'e, но я оставлю их для следующих постов.

К примеру, давайте представим, что у нас есть следующий источник данных (класс GreekGod объявлен в коде):
  1. <Window.Resources>
  2.   <local:GreekGod Name=”ZeusDescription=”Supreme God of the OlympiansRomanName=”Jupiterx:Key=”zeus/>
  3.   <local:GreekGod Name=”PoseidonDescription=”God of the sea, earthquakes and horsesRomanName=”Neptunex:Key=”poseidon/>
  4. </Window.Resources>
  5.  
  6. <StackPanel DataContext=”{StaticResource poseidon}”>
  7.   <TextBlock TextContent=”{Binding Source={StaticResource zeus}, Path=Name}”/>
  8.   <TextBlock TextContent=”{Binding Path=Description}”/>
  9.   <TextBlock TextContent=”{Binding Path=RomanName}”/>
  10. </StackPanel>
* This source code was highlighted with Source Code Highlighter.

Первый TextBlock наследует DataContext от своего предка — StackPanel, к тому же у него указано свойство Source в его Binding'е. В этой ситуации, свойство Source имеет приоритет. Из-за того, что TextBlock получает данные из свойства Name объекта с ключом «zeus», он отобразит слово «Zeus».

У второго TextBlock'а свойство Source не устанавливается напрямую в объекте Binding. Поэтому он наследует DataContext от вышестоящего StackPanel. Как вы могли догадаться, это укажет на свойство Description у ресурса с ключом «poseidon» и на элементе отобразиться надпись «God of the sea, earthquakes and horses».

С третьим TextBlock'ом все так же, как и со вторым. Он отобразит слово «Neptune».

Большинство использующих Data Binding программ, которые я видела, гораздо чаще используют DataContext, что гораздо сложнее, чем Source. Я рекомендую использовать DataContext только там, где вам надо связать более одного свойства от определенного источника. Когда же связывается только одно свойство, я всегда использую Source. Причина этого в том, что так проще для отладки — для того, чтобы понять, что происходит, я бы предпочла видеть всю информацию о Binding'е в одном месте, а не искать ее в ближайшем DataContext'е. В нашем маленьком примере это несложно, но в больших приложениях это сохранит вам немного времени.

Здесь вы можете найти проект для Visual Studio с кодом, который был использован в статье.
Tags:
Hubs:
+12
Comments 15
Comments Comments 15

Articles