我有一个自定义面板,我在其中声明了一个自定义属性来保存内容(我不想将儿童用于内容):
[ContentProperty(Name = "PanelContent")]
public class CustomPanel : Panel
{
public static readonly DependencyProperty PanelContentProperty =
DependencyProperty.Register("PanelContent",
typeof(Collection<UIElement>), typeof(CustomPanel),
new PropertyMetadata(new Collection<UIElement>(), null));
public Collection<UIElement> PanelContent
{
get
{
return (Collection<UIElement>)GetValue(PanelContentProperty);
}
}
}当像这样使用时,这是非常完美的:
<CustomPanel>
<TextBlock>A</TextBlock>
<TextBlock>B</TextBlock>
</CustomPanel>但是,当我想将该面板作为ItemsPanelTemplate在ItemsControl中使用时,ContentProperty属性将被忽略,并将所有内容添加到集合,而不是PanelContent集合中:
<ItemsControl ItemTemplate="{StaticResource ReviewTemplate}" ItemsSource="{Binding Reviews}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<CustomPanel></CustomPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>这不是它的工作方式。根据文档
ItemsPanelTemplate对象元素应该包含一个FrameworkElement派生类,作为项的根元素。在大多数情况下,这是一个面板派生类。扩展模板充当已实现项的父级,并且通常有多个项。因此,ItemsPanelTemplate的预期根元素的XAML内容属性应该像Panel.Children一样支持集合。
发布于 2012-07-26 16:06:28
负责此任务的面板的GenerateChildren方法(如ILSpy中所示)类似于
internal virtual void GenerateChildren()
{
IItemContainerGenerator itemContainerGenerator = this._itemContainerGenerator;
if (itemContainerGenerator != null)
{
using (itemContainerGenerator.StartAt(new GeneratorPosition(-1, 0), GeneratorDirection.Forward))
{
UIElement uIElement;
while ((uIElement = (itemContainerGenerator.GenerateNext() as UIElement)) != null)
{
this._uiElementCollection.AddInternal(uIElement);
itemContainerGenerator.PrepareItemContainer(uIElement);
}
}
}
}如您所见,它总是添加到this._uiElementCollection中,这是支持儿童属性的字段。
发布于 2012-07-21 07:15:42
我认为ItemsPanelTemplate只能将Panel.Children作为布局项的目标。实际上,如果您从(比方说) CustomPanel中派生出ContentControl,您会发现地铁风格的应用程序中有以下异常消息:
Exception: The ItemsControl.ItemsPanelTemplate must have a derivative of Panel as the root element.您所链接的文档可能是一个文档错误,它是从WPF时间复制的,而此时您仍然可以将可视化视图以编程方式插入到可视化树中。在Metro应用程序中,不再有一种不用使用UIElements就可以将自己的Panel.Children列表放到可视化树中的方法。
发布于 2012-07-19 19:13:23
因为ItemsPanelTemplate被ItemsControl用来创建和使用面板,而不是XAML做任何事情。ItemsControl只会简单地调用Panel.Children.Add,而不管ContentProperty设置为什么。
面板应该只对孩子们进行布局,而不对他们进行样式设计。因此,您必须做的所有事情都是重写、安排和度量方法。所有的面板都是这样的。
对于样式和任何其他逻辑,您必须使用另一种方法。
https://stackoverflow.com/questions/11501553
复制相似问题