为什么这不起作用?
在自定义控件的 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);
如您所见,它需要任何对象。我尝试将其更改为网格,但这没有帮助。
它抛出此错误(来自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中定义了。有没有人对此事有任何了解?
非常感谢您的帮助!
答案 0 :(得分:6)
这就是问题所在: -
<Setter Property="ChromeContent">
<Setter.Value>
<Grid />
</Setter.Value>
</Setter>
您不应将UIElement
直接包含在资源字典中或作为样式的值。您可能会将样式视为某种描述符,但事实并非如此。样式中的值是它们所持有的对象的构造实例。您的样式包含Grid
的单个实例。每当使用该样式分配给ChromeContent
属性时,它将尝试为网格提供相同的单个实例。
UIElement
只能是父母一方的孩子。如果您的控件构建了两个实例,会发生什么?将(如果silverlight允许)尝试将Grid的单个实例分配给两个控件。
这是ControlTemplate
和DataTemplate
等模板的一个原因。每次使用模板时都会调用这些标记,而不是在首次解析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" />