【问题标题】:Silverlight Defaulting ContentPresenter ContentSilverlight 默认内容演示者内容
【发布时间】:2011-01-28 14:52:37
【问题描述】:

为什么这不起作用?

generic.xaml 中用于自定义控件:

在应用于自定义控件的样式中...

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>

...

稍后,在控件模板中...

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}" />

这是 ChromeContent 的依赖属性...

public Object ChromeContent
{
  get { return (Object)GetValue(ChromeContentProperty); }
  set { SetValue(ChromeContentProperty, value); }
}
public static readonly DependencyProperty ChromeContentProperty =
    DependencyProperty.Register("ChromeContent", typeof(Object), 
    typeof(casPopup), null);

如您所见,它需要任何对象。我尝试将其更改为 Grid,但这没有帮助。

它抛出这个错误(来自 javascript):_Failed to assign to property 'System.Windows.Controls.ContentPresenter.Content'

奇怪的是,如果我从 setter 中删除 Grid 并只使用文本,则以下操作会正常工作:

<Setter Property="ChromeContent" Value="DEFAULT" />

此外,这也适用于控件类中的 OnApplyTemplate 方法:

  Grid g = new Grid();
  g.Width = 100;
  g.Height = 25;
  g.Background = new SolidColorBrush(Colors.LightGray);
  ChromeContent = g;

我很难理解是什么阻止了在 generic.xaml 中定义的网格的默认内容工作。有人知道这件事吗?

非常感谢您的帮助!

【问题讨论】:

    标签: silverlight custom-controls default contentpresenter


    【解决方案1】:

    这就是问题所在:-

    <Setter Property="ChromeContent">
      <Setter.Value>
        <Grid />
      </Setter.Value>
    </Setter>
    

    您不应将UIElement 直接包含在资源字典中或作为样式的值。您可能会将样式视为某种描述符,但事实并非如此。样式中的值是它们所持有的对象的构造实例。您的样式包含Grid 的单个实例。每当使用该样式分配给 ChromeContent 属性时,它都会尝试分配 Grid 的相同 single 实例。

    UIElement 只能是一个父母的孩子。如果你的控件被构造了两个实例会发生什么?将会(如果 silverlight 允许)尝试将 Grid 的相同 single 实例分配给两个控件。

    这是ControlTemplateDataTemplate 等模板的原因之一。每次使用模板时都会调用其中的标记,而不是在第一次解析 Xaml 时调用。

    编辑

    要回答你的补充问题,你应该默认另一个DataTemplate类型的属性:-

    <Setter Property="ChromeContentTemplate">
      <Setter.Value>
        <DataTemplate>
          <Grid />
        </DataTemplate>
      </Setter.Value>
    </Setter>
    

    属性:-

    public Object ChromeContentTemplate
    {
      get { return (DataTemplate)GetValue(ChromeContentTemplateProperty); }
      set { SetValue(ChromeContentTemplateProperty, value); }
    }
    
    public static readonly DependencyProperty ChromeContentTemplateProperty=
        DependencyProperty.Register("ChromeContentTemplate", typeof(DataTemplate), 
        typeof(casPopup), null);
    

    控制模板:-

    <ContentPresenter Grid.Column="0" 
         x:Name="ChromeContentPresenter" 
         Content="{TemplateBinding ChromeContent}"
         ContentTemplate="{TemplateBinding ChromeContentTemplate" />
    

    【讨论】:

    • 哇,很有趣。我不知道这个。如果可以的话,一个后续问题:我将如何使用控制模板执行此操作?当我尝试在 ContentPresenter 中放置默认标记时,我无法添加网格等内容。我确实希望用户的内容在他们提供时覆盖我的内容,所以我不确定从这里去哪里。
    • 知道了。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多