Silverlight默认ContentPresenter内容

mau*_*kye 5 silverlight default custom-controls contentpresenter

为什么这不起作用?

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

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

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

...

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

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}" />
Run Code Online (Sandbox Code Playgroud)

这是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);
Run Code Online (Sandbox Code Playgroud)

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

它抛出此错误(来自javascript):_无法分配给属性'System.Windows.Controls.ContentPresenter.Content'

奇怪的是,如果我从setter中删除网格并使用文本,以下内容将正常工作:

<Setter Property="ChromeContent" Value="DEFAULT" />
Run Code Online (Sandbox Code Playgroud)

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

  Grid g = new Grid();
  g.Width = 100;
  g.Height = 25;
  g.Background = new SolidColorBrush(Colors.LightGray);
  ChromeContent = g;
Run Code Online (Sandbox Code Playgroud)

我很难理解什么阻止了网格的默认内容,在generic.xaml中定义了.有没有人对此事有任何了解?

非常感谢您的帮助!

Ant*_*nes 6

这就是问题:-

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

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

A UIElement只能是父母一方的孩子.如果您的控件构建了两个实例,会发生什么?将(如果silverlight允许)尝试将Grid 的同一单个实例分配给两个控件.

这是模板的一个原因,如ControlTemplateDataTemplate.每次使用模板时都会调用这些标记,而不是在首次解析Xaml时调用.

编辑:

要回答你的补充问题,你应该默认另一种类型的财产DataTemplate: -

<Setter Property="ChromeContentTemplate">
  <Setter.Value>
    <DataTemplate>
      <Grid />
    </DataTemplate>
  </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

属性:-

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);
Run Code Online (Sandbox Code Playgroud)

控制模板: -

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}"
     ContentTemplate="{TemplateBinding ChromeContentTemplate" />
Run Code Online (Sandbox Code Playgroud)