WPF:无法在属性元素上设置属性怪异

时间:2009-10-12 10:18:38

标签: c# .net wpf xaml properties

private TextBlock _caption = new TextBlock();

public TextBlock Caption  
{  
    get { return _caption; }  
    set { _caption = value; }  
}

<l:CustomPanel>  
    <l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />  
</l:CustomPanel>

给我以下错误:
无法在属性元素上设置属性。

如果我使用:

<l:CustomPanel>  
    <l:CustomPanel.Caption>
        <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
    </l:CustomPanel.Caption>
</l:CustomPanel>

我的TextBlock显示正常,但它嵌套在另一个TextBlock中,就像这样,它甚至似乎将自己添加到Caption属性之外:

<l:CustomPanel>  
    <l:CustomPanel.Caption>
        <TextBlock>
             <InlineUIContainer>
                 <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
             </InlineUIContainer>
        </TextBlock>
    </l:CustomPanel.Caption>

    <TextBlock>
         <InlineUIContainer>
             <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
         </InlineUIContainer>
    </TextBlock>
</l:CustomPanel>

正如您可能已经猜到的那样,我希望我的代码可以在自定义面板上设置我的Caption属性,如果可能的话。

我也尝试使用DependencyProperty相同的代码无济于事。

那么,有谁可以帮我解决这个问题?

3 个答案:

答案 0 :(得分:13)

我可以解释出现了什么问题以及如何解决它。

首先,

<l:CustomPanel>
  <l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" />

是一个简单的语法错误。 <l:CustomPanel.Caption>语法不接受XML属性 - 属性值必须在元素内。

这是正确的属性元素语法:

<l:CustomPanel>    
  <l:CustomPanel.Caption>  
    <TextBlock Text="Caption text" FontSize="18" Foreground="White" />   
  </l:CustomPanel.Caption>  
</l:CustomPanel>

但:

  1. 属性元素语法仅适用于DependencyProperties(因此它不适用于您的CLR属性)和
  2. 属性元素语法始终遵循属性类型
  3. 的ContentPropertyAttribute

    由于TextBlock具有[ContentPropertyAttribute(“Inlines”)],因此属性元素语法正在尝试将TextBlock添加到Inlines集合中。

    解决方案很简单:将属性声明为类型为 UIElement 的DependencyProperty,而不是类型 TextBlock 。这具有额外的优点,即不将内容的显示限制为仅仅TextBlock。如果您确实想将其限制为TextBlock,则可以使用验证回调。

    public UIElement Content { get { ...
    public static readonly DependencyProperty ContentProperty = ...
    

答案 1 :(得分:2)

刚从我的一位同事那里得到了一个非理想的解决方法。它涉及将Caption属性声明为如下资源:

<Page.Resources>
    <TextBlock x:Key="test" Text="Caption text" FontSize="18" Foreground="White" />
</Page.Resources>

<l:CustomPanel Caption="{StaticResource test}" />

我仍然想知道为什么我不能使用前两个选项,所以如果有人知道请回答。 :)

答案 2 :(得分:0)

如果在元素上指定命名空间,似乎可以获得此错误(至少在Silverlight 4和5中)。例如:

<Path>
    <MapLayer.Position xmlns="clr-namespace:Microsoft.Maps.MapControl">
        ...

在这种情况下,MapLayer.Position是附加属性。似乎Silverlight解析器要求使用前缀

定义命名空间
<Path xmlns:map="clr-namespace:Microsoft.Maps.MapControl">
    <map:MapLayer.Position>
        ...