我在 VS 14 CTP 中新建了一个空的 app store 项目名叫 PlayWithXaml ,项目的 MainPage.xaml 文件改为了以下内容:

<Page
x:Class="PlayWithXaml.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PlayWithXaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<local:String x:Key="MyText">
I don't feel good
</local:String>
</Page.Resources>
<Grid>
<Button Content="{StaticResource ResourceKey=MyText}" />
</Grid>
</Page>

现在的问题是我们先要在 PlayWithXaml 名字空间加入我们的 String 类。

namespace PlayWithXaml
{
public class String
{
public string Content { set; private get; }
public override string ToString()
{
return Content;
}
}
}

不幸的是,编译时 VS 告诉我们不能这么做:

Error    1    Missing Content Property definition for Element 'String' to receive content 'I don't feel good'
Error 2 Unknown member '_UnknownContent' on element 'String'
Error 3 The type 'String' does not support direct content.

如果要修改,我们可以从原来的 xaml 文件下手。为我们的目的着想,可以调整一下前面的 xaml 文件的名字空间:

<p:Page
x:Class="PlayWithXaml.MainPage"
xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="using:PlayWithXaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{p:ThemeResource ApplicationPageBackgroundThemeBrush}">
<p:Page.Resources>
<String x:Key="MyText">
I don't feel good
</String>
</p:Page.Resources>
<p:Grid>
<p:Button Content="{p:StaticResource ResourceKey=MyText}"/>
</p:Grid>
</p:Page>

我们把注意力集中在 MyText 字符串资源的声明上:

<String x:Key="MyText">I don't feel good</String>

我们把他改成:

<String x:Key="MyText" Content="I don't feel good"/>

这下编译就通过了。

或者我们可以改为更冗长的、语义相同的另一种形式:

<String x:Key="MyText" >
<String.Content>I don't feel good</String.Content>
</String>

是不是看上去更接近目标了?这次多了一个叫 String.Content 的 XAML 节点,也许看上去比前一个方案更糟糕了。

幸运的是, XAML 本身内建了一种机制,允许我们以一开始期望的那种方式做声明:

<String x:Key="MyText">I feel quite good</String>

在 WPF 中我们需要的是一个自定义的 attribute ,System.Windows.Markup.ContentPropertyAttribute(点击访问 MSDN 文档)。在 Windows Phone app 开发中这个 attribute 是 Windows.UI.Xaml.Markup.ContentPropertyAttribute (点击访问 MSDN 文档)

我们需要做的就是给我们的 String 类添加这个 attribute :

namespace PlayWithXaml
{
using Windows.UI.Xaml.Markup;
[ContentProperty(Name = "Content")]
public class String
{
public string Content { set; private get; }
public override string ToString()
{
return Content;
}
}
}

于是大功告成。

05-21 09:31