最近开发一个自定义Silverlight Control时, 遇到一件莫名其妙的事情:
我这里的自定义控件继承自ContentControl, 其样式定义如下:
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dc:XXXX">
<Grid Name="MainGrid" Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
...
<ContentPresenter Name="ImagePresenter" Margin="4,0" MinWidth="16" VerticalAlignment="Center" HorizontalAlignment="Center"
Content="{TemplateBinding Image}" />
<ContentPresenter Name="HeaderPresenter" Margin="2,0,0,0" Grid.Column="1" VerticalAlignment="Center"
Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" />
<VisualStateManager.VisualStateGroups>
... </VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
使用这个控件,我对其ContentTemplate指定一个DataTemplate, 而运行后,ImagePresenter并没有显示一个有效的Image (尽管我可以保证DataBinding是没有问题的)。
但是ImagePresenter却莫名其妙的 显示了前面提到的DataTempalte的东西。
经过推敲,大概是ImagePresenter这个ContentPresenter的ContentTemplate默认集成了父控件的ContentTemplate的值。
那如何阻止它这样的默认的集成能力呢?
因为我发现 HeaderPresenter并没有像ImagePresenter元素那样, 而是显示了正常的值。不同的就在于HeaderPresenter指定了 ContentTemplate,似乎因为有指定,所以没有被默认为父控件的ContentTemplate的值。
所以,给ImagePresenter加上ContentTemplate的绑定语法, 但是它这里只是显示一个image 并不需要复杂的Template, 原则上只需要制定Content即可。那么有没有语法可以指定ImagePresenter的ContentTemplate为 “Null” 呢。
x:Null 这个xaml的标记扩展,就是完成这件事情。
“将 null 指定为通过 XAML 属性 (Attribute) 设置的属性 (Property) 的值。”
<object property="{x:Null}" .../>
在许多托管编程语言中,null 引用的关键字是 null。 在 Visual Basic 中,null 引用的关键字是 Nothing。
x:Null 标记扩展没有可设置的属性。
请注意,null 不一定是引用类型依赖项属性的初始未设置值。 每个依赖项属性的初始默认值可以不同。 许多依赖项属性由于它们的内部实现将不接受 null 作为值,不管是通过标记还是代码。 在这种情况下,使用 x:Null 设置 XAML 属性值可导致分析程序异常。
x:Null 是标记扩展。 XAML 中的标记扩展使用 XAML 处理器实现识别的 { 和 } 字符将对属性值的处理转义为非文字或处理程序引用。 特性语法是最常用于此标记扩展的语法。 x:Null 还可以在属性元素语法中使用。
某些 Silverlight 类型是可以为 null 的类型。 在可以为 null 的类型还没有将 null 作为默认值的情况下,可以使用 x:Null 在 XAML 中设置 null值。
如果目标为 Silverlight 3,则无法使用对象元素形式 <x:Null>
Jack.
2012-05-07 NJ. USA.