В этой статье в качестве примера приводится ContextMenu, в котором не происходит связывание.
Ник в Silverlight и WPF
Что такое контекст наследования?
Ник Крамер [MSFT] 17 августа 2006 г.
Но прежде чем я расскажу вам о контекстах наследования, я должен объяснить проблему, которую он решает.Когда-то давно наследование свойств смотрело только на логическое дерево и визуальное дерево - поэтому, если у элемента не было логического или визуального родителя, его свойства не наследовали значения от родительского элемента, которого у него не было.Что имеет смысл, если вы думаете о мире с точки зрения кода.Но если вы посмотрите на мир через очки xaml, во многих местах один элемент выглядит так, как будто у него есть родитель, а на самом деле его нет.Рассмотрим следующее:
<Button>
<Button.Background>
<SolidColorBrush>green</SolidColorBrush>
</Button.Background>
</Button>
Быстро, что является родителем SolidColorBrush?Если бы вы сказали Button, вы бы ошиблись - SolidColorBrush не является частью визуального дерева (это не Visual).SolidColorBrush также не является частью логического дерева, потому что если вы вызываете Button.Content, ответ не будет SolidColorBrush.Таким образом, SolidColorBrush в этом примере не имеет родителя, поэтому он не наследует значения свойств от кого-либо.
Сначала это может показаться академическим - кого волнует, наследует ли SolidColorBrush?На самом деле, есть пара причин, по которым это важно: свойство DataContext и событие Loaded.DataContext - это унаследованное свойство, которое использует источник данных по умолчанию для ваших операторов {Binding}.Когда вы пишете:
<SolidColorBrush Color="{Binding}"/>
Поскольку вы не указали источник данных (и кто это делает), он использует свойство DataContext.И если это наследует, как вы ожидаете, все будет счастливым.Но это легко написать:
<Button DataContext="whatever">
<Button.Background>
<SolidColorBrush Color="{Binding}"/>
</Button.Background>
</Button>
И запутайтесь, что ваш SolidColorBrush не наследовал DataContext.Аналогично, событие Loaded изначально было привязано к логическому дереву, поэтому, если вы поместите ваш MediaElement в VisualBrush, в визуальном дереве будет пробел, и ваши медиа никогда не получат событие Loaded и никогда не начнут воспроизводить видео.
И именно поэтому мы изобрели контекст наследования.Вы можете думать об этом как о логическом дереве 2.0 - контекст наследования является дополнительным указателем, который механизм свойств использует, когда нет логического родителя или визуального родителя для получения значений.Контекст наследования не решает все проблемы в этом пространстве, но они решают многие из них, и в будущем мы добавим больше указателей контекста наследования и решим больше проблем.
Есть ряд мест, которые мы устанавливаемУказатели контекста наследования, я не буду пытаться перечислить их все, но вот некоторые из наиболее интересных:
Возможность замораживания внутри FrameworkElement - наш образец SolidColorBrush / Button над FrameworkElement внутри триггеров и сеттеров VisualBrush
Ресурсные словари представляют еще один интересный случай.Предположим, вы используете DynamicResource внутри словаря ресурсов:
Оценивается ли этот динамический ресурс там, где был определен SolidColorBrush?Или где кисть привыкает?Если последнее, что произойдет, если вы используете SolidColorBrush в двух разных местах, где DynamicResource даст два разных ответа?Это может показаться надуманным:
<Window.Resources>
`<Color x:Key="color">red</Color>`
`<SolidColorBrush x:Key="brush" Color="{DynamicResource color}" /> `
</Window.Resources>
<Button>
<Button.Background>
<StaticResource ResourceKey="brush"/>
</Button.Background>
</Button>
<Button>
<Button.Resources>
<Color x:Key="color">blue</Color>
</Button.Resources>
<Button.Background>
<StaticResource ResourceKey="brush"/>
</Button.Background>
</Button>
Но на самом деле это происходит в реальном коде.Мы выбрали первое решение, контекст наследования для SolidColorBrush указывает на ресурссловарь, а не его смысл.
Контекст наследования был удивительно полезен, но мы не
контекстные ссылки наследования везде, где это теоретически возможно,
в основном из-за времени суток (добавление ссылок на контекст наследования
очень сложно реализовать качественно и не вызывая
нежелательные изменения поведения). Вероятно, самый простой пример того, где
у нас нет контекстных ссылок наследования через случайное свойство
элементы:
<Button>
<Button.ContextMenu>
<ContextMenu/>
</Button.ContextMenu>
</Button>
ContextMenu не является ни визуальным, ни логическим потомком Button, ни
один из случаев контекста наследования, перечисленных выше (ContextMenu не
Freezable). Но, имея в своем распоряжении концепцию контекста наследования,
мы надеемся решить эту проблему в будущих версиях WPF.