При создании объекта в xaml DataContext, по-видимому, в большинстве случаев правильно разрешается, но создание этого же объекта непосредственно в области действия Присоединенного свойства, по-видимому, блокирует наследование DataContext.
В этом случае Есть несколько определений, необходимых для отдыха. Я рад показать код, но для краткости вот схема:
- Модель представления,
ViewModel
, со свойством, ViewModel.MyProperty
типа string, установленного на "123456789abc"
- Пользовательский объект,
class FrameworkObject : FrameworkElement
- пользовательский интерфейс не определен, но имеет DataContext. Этот объект имеет определенное свойство зависимости string FrameworkObject.MyDependencyProperty
- Присоединенное свойство
AttachedProperty.FrameworkObject
, которое принимает объект типа FrameworkObject
- A. Net Framework WPF Application, где мы проведет тестирование
Создание объекта как элемента в Visual Tree успешно связывает значение
<!--
System.Windows.Data Warning: 56 : Created BindingExpression (hash=52203868) for Binding (hash=27504314)
System.Windows.Data Warning: 58 : Path: 'MyProperty'
System.Windows.Data Warning: 60 : BindingExpression (hash=52203868): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=52203868): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=52203868): Attach to StackOverflowExamples.FrameworkObject.MyProperty (hash=34181910)
System.Windows.Data Warning: 67 : BindingExpression (hash=52203868): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=52203868): Found data context element: FrameworkObject (hash=34181910) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=52203868): Activate with root item ViewModel (hash=66824994)
System.Windows.Data Warning: 108 : BindingExpression (hash=52203868): At level 0 - for ViewModel.MyProperty found accessor RuntimePropertyInfo(MyProperty)
System.Windows.Data Warning: 104 : BindingExpression (hash=52203868): Replace item at level 0 with ViewModel (hash=66824994), using accessor RuntimePropertyInfo(MyProperty)
System.Windows.Data Warning: 101 : BindingExpression (hash=52203868): GetValue at level 0 from ViewModel (hash=66824994) using RuntimePropertyInfo(MyProperty): '123456789abc'
System.Windows.Data Warning: 80 : BindingExpression (hash=52203868): TransferValue - got raw value '123456789abc'
System.Windows.Data Warning: 89 : BindingExpression (hash=52203868): TransferValue - using final value '123456789abc'
-->
<local:FrameworkObject x:Name="CreatedInPanel" MyDependencyProperty="{Binding MyProperty, diag:PresentationTraceSources.TraceLevel=High}" />
<TextBlock local:AttachedProperty.FrameworkObject="{Binding Path='', ElementName=CreatedInPanel}" Style="{StaticResource DisplayFromAttached}" />
Создание объекта в области действия TextBlock не может быть правильно привязано
<!--
System.Windows.Data Warning: 56 : Created BindingExpression (hash=53517805) for Binding (hash=3663598)
System.Windows.Data Warning: 58 : Path: 'MyProperty'
System.Windows.Data Warning: 60 : BindingExpression (hash=53517805): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=53517805): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=53517805): Attach to StackOverflowExamples.FrameworkObject.MyProperty (hash=51442863)
System.Windows.Data Warning: 67 : BindingExpression (hash=53517805): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=53517805): Found data context element: FrameworkObject (hash=51442863) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=53517805): DataContext is null
System.Windows.Data Warning: 65 : BindingExpression (hash=53517805): Resolve source deferred
System.Windows.Data Warning: 67 : BindingExpression (hash=53517805): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=53517805): Found data context element: FrameworkObject (hash=51442863) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=53517805): DataContext is null
System.Windows.Data Warning: 67 : BindingExpression (hash=53517805): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=53517805): Found data context element: FrameworkObject (hash=51442863) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=53517805): DataContext is null
System.Windows.Data Warning: 67 : BindingExpression (hash=53517805): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=53517805): Found data context element: FrameworkObject (hash=51442863) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=53517805): DataContext is null
System.Windows.Data Warning: 67 : BindingExpression (hash=53517805): Resolving source (last chance)
System.Windows.Data Warning: 70 : BindingExpression (hash=53517805): Found data context element: FrameworkObject (hash=51442863) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=53517805): Activate with root item <null>
System.Windows.Data Warning: 106 : BindingExpression (hash=53517805): Item at level 0 is null - no accessor
System.Windows.Data Warning: 80 : BindingExpression (hash=53517805): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=53517805): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=53517805): TransferValue - using final value ''
-->
<TextBlock Style="{StaticResource DisplayFromAttached}">
<local:AttachedProperty.FrameworkObject>
<local:FrameworkObject x:Name="CreatedInScope" MyDependencyProperty="{Binding MyProperty, diag:PresentationTraceSources.TraceLevel=High}" />
</local:AttachedProperty.FrameworkObject>
</TextBlock>
Использование прокси-сервера данных разрешит привязку даже при создании в области управления элемента управления
<!--
System.Windows.Data Warning: 56 : Created BindingExpression (hash=6968762) for Binding (hash=14964341)
System.Windows.Data Warning: 58 : Path: 'DataContext.MyProperty'
System.Windows.Data Warning: 60 : BindingExpression (hash=6968762): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=6968762): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=6968762): Attach to StackOverflowExamples.FrameworkObject.MyProperty (hash=47145209)
System.Windows.Data Warning: 67 : BindingExpression (hash=6968762): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=6968762): Found data context element: <null> (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=6968762): Activate with root item FrameworkElement (hash=339559)
System.Windows.Data Warning: 108 : BindingExpression (hash=6968762): At level 0 - for FrameworkElement.DataContext found accessor DependencyProperty(DataContext)
System.Windows.Data Warning: 104 : BindingExpression (hash=6968762): Replace item at level 0 with FrameworkElement (hash=339559), using accessor DependencyProperty(DataContext)
System.Windows.Data Warning: 101 : BindingExpression (hash=6968762): GetValue at level 0 from FrameworkElement (hash=339559) using DependencyProperty(DataContext): <null>
System.Windows.Data Warning: 106 : BindingExpression (hash=6968762): Item at level 1 is null - no accessor
System.Windows.Data Warning: 80 : BindingExpression (hash=6968762): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=6968762): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=6968762): TransferValue - using final value ''
System.Windows.Data Warning: 96 : BindingExpression (hash=6968762): Got PropertyChanged event from FrameworkElement (hash=339559) for DataContext
System.Windows.Data Warning: 101 : BindingExpression (hash=6968762): GetValue at level 0 from FrameworkElement (hash=339559) using DependencyProperty(DataContext): ViewModel (hash=66824994)
System.Windows.Data Warning: 108 : BindingExpression (hash=6968762): At level 1 - for ViewModel.MyProperty found accessor RuntimePropertyInfo(MyProperty)
System.Windows.Data Warning: 104 : BindingExpression (hash=6968762): Replace item at level 1 with ViewModel (hash=66824994), using accessor RuntimePropertyInfo(MyProperty)
System.Windows.Data Warning: 101 : BindingExpression (hash=6968762): GetValue at level 1 from ViewModel (hash=66824994) using RuntimePropertyInfo(MyProperty): '123456789abc'
System.Windows.Data Warning: 80 : BindingExpression (hash=6968762): TransferValue - got raw value '123456789abc'
System.Windows.Data Warning: 89 : BindingExpression (hash=6968762): TransferValue - using final value '123456789abc'
-->
<ContentControl Content="{StaticResource DataProxy}" Visibility="Collapsed" />
<TextBlock Style="{StaticResource DisplayFromAttached}">
<local:AttachedProperty.FrameworkObject>
<local:FrameworkObject x:Name="DataProxyBinding" MyDependencyProperty="{Binding DataContext.MyProperty, Source={StaticResource DataProxy}, diag:PresentationTraceSources.TraceLevel=High}" />
</local:AttachedProperty.FrameworkObject>
</TextBlock>
И самое сбивающее с толку меня. Построение FrameworkObject
в пределах ContentControl.Content
, кажется, отлично связывает
<!--
System.Windows.Data Warning: 56 : Created BindingExpression (hash=63642613) for Binding (hash=38750844)
System.Windows.Data Warning: 58 : Path: 'MyProperty'
System.Windows.Data Warning: 60 : BindingExpression (hash=63642613): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=63642613): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=63642613): Attach to StackOverflowExamples.FrameworkObject.MyProperty (hash=16347077)
System.Windows.Data Warning: 67 : BindingExpression (hash=63642613): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=63642613): Found data context element: FrameworkObject (hash=16347077) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=63642613): Activate with root item ViewModel (hash=66824994)
System.Windows.Data Warning: 108 : BindingExpression (hash=63642613): At level 0 - for ViewModel.MyProperty found accessor RuntimePropertyInfo(MyProperty)
System.Windows.Data Warning: 104 : BindingExpression (hash=63642613): Replace item at level 0 with ViewModel (hash=66824994), using accessor RuntimePropertyInfo(MyProperty)
System.Windows.Data Warning: 101 : BindingExpression (hash=63642613): GetValue at level 0 from ViewModel (hash=66824994) using RuntimePropertyInfo(MyProperty): '123456789abc'
System.Windows.Data Warning: 80 : BindingExpression (hash=63642613): TransferValue - got raw value '123456789abc'
System.Windows.Data Warning: 89 : BindingExpression (hash=63642613): TransferValue - using final value '123456789abc'
-->
<ContentControl x:Name="ImplicitContent">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<TextBlock local:AttachedProperty.FrameworkObject="{TemplateBinding Content}" Style="{StaticResource DisplayFromAttached}" />
</ControlTemplate>
</ContentControl.Template>
<local:FrameworkObject MyDependencyProperty="{Binding MyProperty, diag:PresentationTraceSources.TraceLevel=High}" />
</ContentControl>
. В этом я использовал стиль DisplayFromAttached
, который находится в словаре ресурсов вложенной панели. и определяется следующим образом:
<Style x:Key="DisplayFromAttached" TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Path=(local:AttachedProperty.FrameworkObject).MyDependencyProperty, RelativeSource={RelativeSource Self}}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(local:AttachedProperty.FrameworkObject).MyDependencyProperty, RelativeSource={RelativeSource Self}}" Value="">
<Setter Property="Text" Value="No value found" />
</DataTrigger>
</Style.Triggers>
</Style>
Почему DataContext не наследуется объекту, созданному непосредственно как присоединенное свойство?