2010-09-01 14 views
12

J'ai une page page dans un cadre frame, avec frame.DataContext = "foo".page.DataContext n'est pas hérité du parent Frame?

  • (page.Parent as Frame).DataContext est "foo". ok
  • BindingExpression pour page.DataContext est null (également forcé avec ClearValue). ok
  • page.DataContext est null. mais je m'attendais à "foo"!

Pourquoi le DataContext n'est-il pas hérité? Pour autant que je understand le cadre sandboxes le contenu. Mais je n'ai pas trouvé de documentation sur ce comportement - quelqu'un peut-il me diriger vers un endroit où cela est mentionné?

+0

Le BindingExpresion n'est pas passé à l'élément enfant, mais le DataContext est. Avez-vous vérifié la propriété DataContext elle-même? – Carlo

+0

Oui, DataContext est également null. Il reste 'null' même après avoir appelé ClearValue. –

+0

Merci de poser cette question: 0) Comme une note en changeant le datacontext du contrôle utilisateur hébergeant le cadre après que tout a été chargé (* après * l'événement chargé) la page hérite du nouveau datacontext (doit effacer et remettre à zéro à l'original, ou ne pas être défini avant la fin de l'événement chargé). – paulecoyote

Répondre

12

Pour répondre à votre question à propos de la documentation de ce comportement: Il ne s'agit pas de la documentation Microsoft, mais j'ai quelques livres WPF qui en font mention.

"Essential Windows Presentation Foundation" dit: (pp 160-161.)

Il existe deux modèles intéressants pour l'hébergement de contenu navigable: isolé d'hébergement et d'hébergement intégré.

Avec isolé hébergeant le contenu n'est pas approuvé et s'exécute dans un environnement complètement isolé (en mode bac à sable). C'est ainsi que le contenu WPF est hébergé lors de son exécution dans le navigateur Web du système en tant qu'application de navigateur XAML. Pour la navigation vers une autre application ou un contenu HTML, ce modèle d'hébergement isolé est pris en charge avec un objet Frame.

Hébergement intégré, dans lequel nous voulons que le contenu se comporte dans le cadre de notre application, n'est pas pris en charge du tout dans le système. Lorsque Frame navigue vers le contenu de l'application, nous obtenons un hybride impair de comportement isolé et intégré. Frame isole son contenu de son style (et le style de ses parents), mais pas du style de l'application. Les événements ne bougent pas à partir du contenu dans Frame; cependant, les objets sont accessibles depuis la propriété Content (ce qui signifie qu'ils ne sont pas isolés dans un sens de sécurité).

Pour toutes ces raisons, Frame est le plus utile lorsque nous travaillons avec un contenu externe, mais il peut être utilisé avec précaution pour le contenu de l'application.

C'est tout ce qu'il a à dire - rien sur l'héritage de la propriété.

"Windows Presentation Foundation Unleashed dit (p 95.).

Le contrôle Frame détient un contenu arbitraire, tout comme tous les autres contrôles de contenu, mais il isole le contenu du reste de l'interface utilisateur, par exemple, des propriétés normalement hérité vers le bas l'arrêt de l'arbre d'élément lorsqu'ils atteignent l'Frame.

21

Vous n'avez pas spécifiquement demandé comment vous pouvez faire ce travail, pourquoi ne ce ne est pas par défaut. Toutefois, si vous ne voulez que vos pages pour hériter DataContext, de l'image que vous pouvez faire ceci:

En XAML:

<Frame Name="frame" 
     LoadCompleted="frame_LoadCompleted" 
     DataContextChanged="frame_DataContextChanged"/> 

En behind:

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; 
} 
+0

Fonctionne comme il se doit :) Merci. – torpederos

1

Pour construire sur @ Joe-blanc de répondre pour ceux qui veulent savoir de façons de faire la Frame en cascade le DataContext, je mentionnerai que cela peut également être effectué en XAML seulement.

<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> 

Pour ceux qui sont nouveaux à WPF, vous pouvez mettre ce XAML dans le fichier App.xaml afin qu'il remplace tous Frame contrôles dans votre application qui ramassent le style par défaut. Cela signifie que vous n'avez pas à écrire de code spécifique derrière chaque fois que vous utilisez un nouveau code Frame.

J'ai utilisé VisualStudio 2015 Visual Designer (voir l'image ci-dessous) pour créer la majeure partie du code XAML ci-dessus, puis ajouté DataContext="{TemplateBinding DataContext}" pour effectuer la cascade.

VS2015 designer

+0

Ne travaillait pas pour moi. J'ai reçu une exception "Impossible de classer" System.Windows.FrameworkTemplate "objet de type" MS.Internal.NamedObject ". – denver