在WinRT中绑定ContentControl的Content属性

Mik*_*tly 6 xaml windows-runtime winrt-xaml visual-studio-2013

假设我有一个Windows应用商店应用(针对Windows 8.1),并且在页面上有一个ContentControl,如下所示:

<ContentControl>
  <ContentControl.Content>
    <TextBlock>Hello world</TextBlock>
  </ContentControl.Content>
</ContentControl>
Run Code Online (Sandbox Code Playgroud)

这工作绝对正常,但如果我尝试将内容设置为资源,如下所示:

<Page.Resources>
  <TextBlock x:Key="TestContent">Hello world</TextBlock>
</Page.Resources>
<ContentControl Content="{StaticResource TestContent}" />
Run Code Online (Sandbox Code Playgroud)

设计器中的一切看起来都很棒,但是我在运行时遇到以下错误:

无法分配给属性'Windows.UI.Xaml.Controls.ContentControl.Content'

我已经尝试在各个地方定义资源(app.xaml,单独的资源文件等),但每次都会得到相同的错误.

所以,我有一些问题:

  1. 这应该在WinRT XAML中可行吗?我只是在做一些愚蠢的事情吗?
  2. 有没有其他方法来资源像这样的任意内容,例如路径数据?(我通过为一个Path元素定义一个样式,在一个setter中配置路径数据,但是在导航回一个页面时它似乎没有重新绑定,我取得了一些有限的成功.尽管这是另一个问题......)

Wir*_*rie 6

通常,资源是共享的"单个实例",并且各种XAML元素指的是单个共享实例.我不确定为什么设计师暗示这会起作用(除了它支持多种类型的"XAML"的遗产).在一个情况下TextBlock,它有点不同,因为您希望Element实例能够被多次复制和实例化(例如,可能在多个ContentControls 中托管).

WPF有一个功能,可以在一个名为的特殊属性中完成这项工作x:Shared.您可以将其设置false为指示a Resource未共享,并且每个资源请求都应返回一个新实例.WinRT没有相同的功能.

但是您可以考虑使用完全受支持的解决方法.

一种选择是使用模板而不是直接替换内容,如您所尝试的:

<Page.Resources>
    <Style x:Name="replacement" TargetType="ContentControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ContentControl">
                    <TextBlock FontSize="100" Foreground="Red">Hello!</TextBlock>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ContentControl Style="{StaticResource replacement}"></ContentControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)

从语法上讲,它当然要长一点,但从功能上来说,它应该是相同的结果.

如果没有x:Shared,您只能绑定到作为内部数据类型的资源,例如x:string(如下例所示):

<Page.Resources>
    <x:String x:Key="tbResource">The Text!</x:String>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
    <ContentControl Content="{StaticResource tbResource}" ></ContentControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)