Silverlight默认的ContentPresenter内容

5

为什么这个不能工作?

在自定义控件的 generic.xaml 中:

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

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

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

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

以下是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):“无法分配给属性'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中定义的网格默认内容的工作。有人对此有什么了解吗?
非常感谢您的帮助!
1个回答

6

这是问题:

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

您不应该直接将UIElement包含在资源字典中或作为样式的值。您可能会认为样式是某种描述符,但实际上它不是。样式中的值是它们所持对象的构造实例。您的样式仅持有一个Grid实例。每当该样式被用于分配给ChromeContent属性时,它都会尝试分配相同的单个Grid实例。 UIElement只能是一个父级的子元素。如果构建了两个控件实例,会发生什么?(如果silverlight让你这样做)那么就会尝试将相同的单个Grid实例分配给这两个控件。
这是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中放置默认标记时,我无法添加像网格之类的东西。我确实希望用户提供内容覆盖我的内容,所以我不确定该怎么做。 - maulkye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接