【问题标题】:WPF: Cannot set properties on property elements weirdnessWPF:无法在属性元素上设置属性
【发布时间】:2010-12-05 22:38:06
【问题描述】:
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>

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

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

那么,谁能帮我解决这个问题?

【问题讨论】:

    标签: c# .net wpf xaml properties


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      首先,

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

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

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

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

      但是:

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

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

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

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

      【讨论】:

      • Thx Ray,那行得通 :) 虽然我不再需要它,但我将来可能需要它,所以谢谢你的清晰解释。
      • 除了,你应该怎么说?有人没有考虑到这一点,并盲目地将其应用于所有属性,甚至是不属于它们的属性。
      【解决方案3】:

      如果您在元素上指定命名空间,您似乎会收到此错误(至少在 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>
              ...
      

      【讨论】:

        猜你喜欢
        • 2020-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-13
        • 2014-12-31
        相关资源
        最近更新 更多