amino - propiedad tag c#
page.DataContext no se hereda de Frame principal? (3)
Tengo una página de page
en un marco de frame
, con frame.DataContext = "foo"
.
-
(page.Parent as Frame).DataContext
es"foo"
. De acuerdo - BindingExpression para
page.DataContext
esnull
(también forzado con ClearValue). De acuerdo -
page.DataContext
esnull
. ¡Pero esperaba "foo"!
¿Por qué no se hereda el DataContext? Por lo que understand los marcos de arena del marco del contenido. Pero no pude encontrar ninguna documentación de este comportamiento. ¿Puede alguien indicarme un lugar donde se mencione esto?
No preguntó específicamente cómo podría hacer que esto funcionara, solo por qué no funciona de manera predeterminada. Sin embargo, si desea que sus Páginas hereden el DataContext del Marco, puede hacer esto:
En XAML:
<Frame Name="frame"
LoadCompleted="frame_LoadCompleted"
DataContextChanged="frame_DataContextChanged"/>
En codebehind:
private void frame_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
UpdateFrameDataContext(sender, e);
}
private void frame_LoadCompleted(object sender, NavigationEventArgs e)
{
UpdateFrameDataContext(sender, e);
}
private void UpdateFrameDataContext(object sender, NavigationEventArgs e)
{
var content = frame.Content as FrameworkElement;
if (content == null)
return;
content.DataContext = frame.DataContext;
}
Para aprovechar la respuesta de @ Joe-White para aquellos que quieran conocer formas de hacer que el Frame
DataContext
cascada en el DataContext
, mencionaré que esto también puede realizarse solo en XAML.
<Style TargetType="{x:Type Frame}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Frame}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<ContentPresenter x:Name="PART_FrameCP" DataContext="{TemplateBinding DataContext}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="NavigationUIVisibility" Value="Visible">
<Setter Property="Template" Value="{StaticResource FrameNavChromeTemplateKey}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="JournalOwnership" Value="OwnsJournal"/>
<Condition Property="NavigationUIVisibility" Value="Automatic"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource FrameNavChromeTemplateKey}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
Para aquellos que son nuevos en WPF, puede colocar este XAML en el archivo App.xaml
para que anule todos los controles de Frame
en su aplicación que seleccionen el estilo predeterminado. Esto significa que no tiene que escribir un código subyacente específico cada vez que use un nuevo Frame
.
Utilicé VisualStudio 2015 Visual Designer (ver la imagen a continuación) para crear la mayor parte del XAML anterior y luego agregué DataContext="{TemplateBinding DataContext}"
para realizar la cascada.
Para responder a su pregunta sobre la documentación de este comportamiento: no es documentación de Microsoft, pero tengo un par de libros de WPF que mencionan esto.
" Essential Windows Presentation Foundation " dice: (pp. 160-161)
Hay dos modelos interesantes para alojar contenido navegable: alojamiento aislado y alojamiento integrado.
Con el alojamiento aislado, el contenido no es de confianza y se ejecuta en un entorno completamente aislado (espacio aislado). Así es como se aloja el contenido de WPF cuando se ejecuta en el navegador web del sistema como una aplicación de navegador XAML. Para navegar a otra aplicación o contenido HTML, este modelo de alojamiento aislado es compatible con un objeto
Frame
.El alojamiento integrado, en el que queremos que el contenido se comporte como parte de nuestra aplicación, no es compatible en absoluto en el sistema. Cuando
Frame
navega al contenido dentro de la aplicación, obtenemos un extraño híbrido de comportamiento aislado e integrado.Frame
aísla su contenido de su estilo (y el estilo de su padre), pero no del estilo de la aplicación. Los eventos no burbujean desde el contenido enFrame
; sin embargo, los objetos son accesibles desde la propiedadContent
(lo que significa que no están aislados en un sentido de seguridad).Por todas estas razones,
Frame
es más útil cuando trabajamos con contenido externo, pero puede usarse con cuidado para el contenido de la aplicación.
Eso es todo lo que tiene que decir, nada sobre la herencia de propiedad.
" Windows Presentation Foundation Unleashed dice (p. 95):
El control
Frame
contiene contenido arbitrario, al igual que todos los demás controles de contenido, pero aísla el contenido del resto de la interfaz de usuario. Por ejemplo, las propiedades que normalmente se heredarían en el árbol de elementos se detienen cuando llegan alFrame
.