page.DataContext不是从父Frame继承的?

时间:2010-09-01 19:24:05

标签: c# wpf binding datacontext msdn

我在page框架中有frameframe.DataContext = "foo"

  • (page.Parent as Frame).DataContext"foo"。的确定
  • page.DataContext的BindingExpression为null(也强制使用ClearValue)。的确定
  • page.DataContextnull但我期待“foo”!

为什么DataContext没有继承?至于我understand Frame 沙箱的内容。但我找不到任何关于这种行为的文件 - 有人能指出我提到这个的地方吗?

3 个答案:

答案 0 :(得分:27)

您没有明确要求 如何使其工作,只有为什么默认情况下不会。但是,如果您希望Pages继承Frame的DataContext,则可以执行以下操作:

在XAML中:

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

在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;
}

答案 1 :(得分:18)

回答有关此行为文档的问题:这不是Microsoft文档,但我有几本WPF书籍都提到了这一点。

Essential Windows Presentation Foundation”说:(第160-161页)

  

托管可导航内容有两个有趣的模型:独立托管和集成托管。

     

使用隔离托管,内容不受信任,并且在完全隔离(沙盒)环境中运行。这是在系统Web浏览器中作为XAML浏览器应用程序运行时托管WPF内容的方式。对于导航到其他应用程序或HTML内容,此Frame对象支持此独立主机模型。

     

我们希望内容在我们的应用程序中运行的集成托管在系统中根本不受支持。当Frame导航到应用程序中的内容时,我们会发现孤立和集成行为的奇怪混合。 Frame将其内容与其样式(及其父样式)隔离开来,但不是从应用程序的样式中隔离出来。事件不会来自Frame中的内容;但是,可以从Content属性访问对象(这意味着它们在安全意义上不是孤立的)。

     

由于所有这些原因,Frame在我们处理外部内容时最有用,但可以小心地用于应用程序内容。

这就是它所要说的 - 没有关于财产继承的事。

Windows Presentation Foundation Unleashed说(第95页):

  

Frame控件保存任意内容,就像所有其他内容控件一样,但它将内容与UI的其余部分隔离开来。例如,通常在元素树下继承的属性在到达Frame时停止。

答案 2 :(得分:2)

对于想要了解Frame级联DataContext的方法的人,建立@ Joe-White的答案,我会提到这也只能在XAML中执行。< / p>

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

对于那些不熟悉WPF的人,可以将此XAML放在App.xaml文件中,以便覆盖应用程序中拾取默认样式的所有Frame控件。这意味着每次使用新的Frame时都不必编写特定的代码隐藏。

我使用VisualStudio 2015可视设计器(见下图)创建了上面的大量XAML,然后添加DataContext="{TemplateBinding DataContext}"来执行级联。

VS2015 designer