page.DataContext 不是从父框架继承的吗?

发布于 2024-09-16 22:16:17 字数 640 浏览 11 评论 0原文

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

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

为什么 DataContext 没有被继承?据我了解< /a> 框架沙箱内容。但我找不到任何有关此行为的文档 - 谁能指出我提到此行为的地方?

I have a Page page in a Frame frame, with frame.DataContext = "foo".

  • (page.Parent as Frame).DataContext is "foo". ok
  • BindingExpression for page.DataContext is null (also forced with ClearValue). ok
  • page.DataContext is null. but I expected "foo"!

Why isn't the DataContext inherited? As far as I understand the Frame sandboxes the content. But I couldn't find any documentation of this behavior - can anyone point me to a place where this is mentioned?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

又怨 2024-09-23 22:16:17

您没有具体询问如何可以实现此功能,只是为什么默认情况下无法实现。但是,如果您确实希望页面继承框架的 DataContext,您可以执行以下操作:

在 XAML 中:

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

You didn't specifically ask how you could make this work, only why it doesn't by default. However, if you do want your Pages to inherit the Frame's DataContext, you can do this:

In XAML:

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

In 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;
}
昇り龍 2024-09-23 22:16:17

回答有关此行为的文档的问题:这不是 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 时停止。

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 in Frame; however, the objects are accessible from the Content 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 the Frame.

蓝海似她心 2024-09-23 22:16:17

对于那些想了解如何使 Frame 级联 DataContext 的人来说,为了以 @Joe-White 的答案为基础,我会提到这也可以在 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 文件中,以便它将覆盖应用程序中采用默认样式的所有 Frame 控件。这意味着您不必在每次使用新的 Frame 时编写特定的后台代码。

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

VS2015 设计器

To build upon @Joe-White's answer for those who want to know of ways to make the Frame cascade the DataContext, I'll mention that this can also be performed in XAML only.

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

For those that are new to WPF, you can put this XAML in the App.xaml file so that it will override all Frame controls in your application that pick up the default style. This means you don't have to write specific code-behind each time you use a new Frame.

I used the VisualStudio 2015 Visual Designer (see pic below) to create the bulk of the XAML above and then added the DataContext="{TemplateBinding DataContext}" to perform the cascade.

VS2015 designer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文