代码之家  ›  专栏  ›  技术社区  ›  Marcel Jackwerth

页面.数据上下文不是从父帧继承的?

  •  20
  • Marcel Jackwerth  · 技术社区  · 14 年前

    我有一页 page 在一个框架中 frame ,与 frame.DataContext = "foo" .

    • (page.Parent as Frame).DataContext "foo" 好 啊
    • 的BindingExpression page.DataContext null (也强制使用ClearValue)。 好 啊
    • 页面.数据上下文 . 但我期待“福”!

    为什么DataContext没有被继承?据我所知 understand 沙盒

    3 回复  |  直到 14 年前
        1
  •  20
  •   Community Lee Campbell    4 年前

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

    " Essential Windows Presentation Foundation

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

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

    集成托管, 在这种情况下,我们希望内容作为应用程序的一部分来运行,但在系统中根本不受支持。什么时候? 框架 导航到应用程序中的内容时,我们得到了一种孤立行为和集成行为的奇怪混合。 将其内容与其样式(及其父级样式)隔离,而不是与应用程序的样式隔离。事件不会从中的内容冒泡 框架 Content 属性(意味着它们在安全意义上不是孤立的)。

    因为这些原因, 框架

    这就是它所要说的——没有财产继承的问题。

    Windows Presentation Foundation Unleashed 说(第95页):

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

        2
  •  32
  •   Goose    11 年前

    怎样 你能让这工作,只有 为什么? 默认情况下不会。但是,如果确实希望页面继承框架的DataContext,可以执行以下操作:

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

    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;
    }
    
        3
  •  2
  •   Rhys    8 年前

    以@Joe White的答案为基础,为那些想知道如何使 Frame DataContext ,我要提到的是,这也只能在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>
    

    对于WPF的新手,可以将这个XAML放在 App.xaml 框架 应用程序中选择默认样式的控件。这意味着您不必在每次使用新代码时都编写特定的代码 .

    我使用VisualStudio2015可视化设计器(见下图)创建了上述XAML的大部分,然后添加了 DataContext="{TemplateBinding DataContext}"

    VS2015 designer