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

Автор оригинала: 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 с кодом, который был использован в статье.
Поделиться публикацией

Похожие публикации

Комментарии 15

    +1
    Несколько простовато. на мой взгляд, можно было бы дополнить пост еще чем-нибудь посложней. Тут, по-моему, все достаточно очевидно :)
    Давайте в следующий раз поговорим о датабайндинге через codebehind вперемешку с xaml )
      0
      ага причем в качестве сорс табличка EF или L2S контекста
        0
        и сценарии master-details
        • НЛО прилетело и опубликовало эту надпись здесь
            0
            трабл в том, что у меня так и не получилось впф нормально с ними работать заставить
            будет время — сяду разобратья с objectdatasource — похоже это единственный способ такое сделать
            разберусь — напишу
              +1
              вроде ведь есть LinqDataSource
                0
                в впф?
                0
                А в чем конкретно проблема-то?
                EF не биндил, а Linq2Sql вполне нормально биндится…
                  0
                  сколько связных таблиц из контекста вы биндили и каким способом?
                    0
                    Контекст такой:


                    Способ — он в xaml-е вроде как один, через биндинг :)
                    Для некоторых отношений, правда, делались CollectionViewSource-ы, т. к. была необходимость фильтровать данные по определенным критериям.
                      0
                      а кусочек не кинете собственно биндинга?
                      вы обертки например ObservableCollection делали для таблиц? а контекст у вас синглтон был или создавали на каждое обновление? окошко было одно? или под каждую таблицу свое?

                      биндинг то он один, вопрос к чему конкретно вы wpf-ные объекты биндили)
            +1
            Просто у меня была идея хронологически перевести все блоги) Просто для новичков такие статьи могут оказаться полезными. Хочу спросить, стоит так делать или же переводить только статьи, где рассматриваются сложные вопросы?
              0
              сложно сказать, конечно простые how-to нужны, другое дело, что многие из них дублируют то что есть на msdn
                +2
                Переводить в первую очередь надо те статьи, которые раскрывают идеологию программирования в WPF. А то народ до сих пор уверен, что WPF — это красивые кнопки и размытый текст.

                Вот статьи, показывающие преимущества WPF:
                The power of Styles and Templates in WPF — идеальный вариант.
                Master-detail scenario
                How do I display some items differently based on one of their properties?
                How do I display items in an ItemsControl using different templates?

                Здесь можно увидеть доклад Беатрис Коста «Data Binding in WPF», сделанный на WPF Bootcamp 2007. Впрочем, там можно увидеть и все отсальные доклады и скачать примеры лабораторных приложений.
              0
              Немного неверное название статьи дано автором. Если он задался вопросом «Как решить, что использовать: DataContext или Source?». То должен был ответить на такие вопросы: какие способы есть, когда их лутше применять, для чего, как это повлияет на производительность и расширяемость. А в этой статье я этого так и не увидел…

              PS: Хотя хорошее дело делаете — WPF в массы!!! :)

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое