page.DataContext not inherited from parent Frame?
To answer your question about documentation of this behavior: It's not Microsoft documentation, but I have a couple of WPF books that both mention this.
"Essential Windows Presentation Foundation" says: (pp. 160-161)
There are two interesting models for hosting navigable content: isolated hosting and integrated hosting.
With isolated hosting the content is not trusted and is run in a completely isolated (sandboxed) environment. This is how WPF content is hosted when running in the system Web browser as a XAML Browser Application. For navigation to another application or HTML content, this isolated hosting model is supported with a
Frame
object.Integrated hosting, in which we want the content to behave as part of our application, is not supported at all in the system. When
Frame
navigates to content within the application, we get an odd hybrid of isolated and integrated behavior.Frame
isolates its content from its style (and its parent's style), but not from the application's style. Events don't bubble from the content inFrame
; however, the objects are accessible from theContent
property (meaning that they aren't isolated in a security sense).For all these reasons,
Frame
is most useful when we're working with external content, but it can be carefully used for application content.
That's all it has to say -- nothing about property inheritance.
"Windows Presentation Foundation Unleashed says (p. 95):
The
Frame
control holds arbitrary content, just like all other content controls, but it isolates the content from the rest of the UI. For example, properties that would normally be inherited down the element tree stop when they reach theFrame
.
WPF UserControl doesn't inherit parent DataContext
The UserControl is actually inheriting the DataContext from its parent element. There is however no TextFromParent
property in that DataContext (because it is the MainWindow instance).
The Binding in the UserControl's XAML is supposed to bind to a property of the UserControl itself, not one of the current DataContext. Hence it must use the UserControl instance as source object:
<TextBlock Text="{Binding TextFromParent,
RelativeSource={RelativeSource AncestorType=UserControl}}" />
Setting the UserControl's DataContext to itself is not an option, because it prevents that a DataContext value is inherited from the parent element of the control.
You may however set the DataContext of the root element in the UserControl's XAML to avoid setting RelativeSource on potentially many Bindings:
<UserControl ...>
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock Text="{Binding TextFromParent}" />
</Grid>
</UserControl>
Why does DataContext fail to inherit on objects constructed as attached properties?
Why would it?
Let's remember that FrameworkElement.DataContext
is implemented as a DependencyProperty
with inheritance flag (see code source here, line 2704) and as such, the "inheritance" of the DataContext
you are talking about takes place according to the documented inheritance rules:
Property value inheritance enables child elements in a tree of elements to obtain the value of a particular property from parent elements.
Property value inheritance is particularly about how property values can inherit from one element to another on the basis of the parent-child relationships within a tree of elements
In your case, there is no such parent-child relationship between your TextBlock
and its AttachedProperty.FrameworkObject
value, not in the WPF sense. The fact that it is an attached or not dependency property doesn't have an impact actually.
Some comments on your attempts
Creating the object as an element in the Visual Tree successfully binds the value
Yes, because then the object inherits the same DataContext
as the TextBlock
because they have the same parent in the element tree.
Creating the object within the scope of the TextBlock fails to bind properly
Yes, because the TextBlock
is not a parent of the object in the element tree. The TextBlock
just happens to hold a reference to that object (I'm hiding the complexity of attached properties here).
Using a data proxy will resolve the binding even when created in a control's scope
Yes, because the object is the child of a ContentControl
itself a child of an element with the correct DataContext
.
And the most confusing to me. Constructing the FrameworkObject within a ContentControl.Content seems to bind perfectly fine.
Same as above.
If you really need your object to have a DataContext
in your second scenario, you have to set it yourself because it won't be naturally inherited:
<TextBlock x:Name="textBlock" Style="{StaticResource DisplayFromAttached}">
<local:AttachedProperty.FrameworkObject>
<local:FrameworkObject DataContext="{Binding ElementName=textBlock, Path=DataContext}" x:Name="CreatedInScope" MyDependencyProperty="{Binding MyProperty, diag:PresentationTraceSources.TraceLevel=High}" />
</local:AttachedProperty.FrameworkObject>
</TextBlock>
How to use the DataContext of a parent class correctly
The content of the Frame
element is not part of visual / logical tree and hence will not persist the data context. You will have to set it explicitly.
<Frame Source="Page1.xaml" Navigated="Frame_Navigated"/>
private void Frame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
((FrameworkElement) e.Content).DataContext = this.DataContext;
}
Hope this helps...
Related Topics
What Does Synchronizationcontext Do
Opening a Folder in Explorer and Selecting a File
Debugging Automatic Properties
How to Convert an Object to a Byte Array in C#
How to Extract Data from a Datatable
Cross Platform (PHP to C# .Net) Encryption/Decryption with Rijndael
How to Return Text from Native (C++) Code
How to Get Memcached Running on a Windows (X64) 64Bit Environment
Jit Compiler VS Offline Compilers
Query an Xdocument for Elements by Name at Any Depth
Can't Connect to Localhost on SQL Server Express 2012/2016
Log4Net Rolling Daily Filename with Date in the File Name
Copy Constructor Versus Clone()
How to Determine the Standard Deviation (Stddev) of a Set of Values
How to Return PDF to Browser in MVC
Validation: How to Inject a Model State Wrapper with Ninject
An Attribute Argument Must Be a Constant Expression, ...- Create an Attribute of Type Array