模板
<Style TargetType="{x:Type local:Viewport}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Viewport}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ItemsPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas x:Name="PART_Canvas" IsItemsHost="True"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
以及OnApplyTemplate 中的代码
content = this.Template.FindName("PART_Canvas", this) as FrameworkElement;
内容总是返回null,为什么它不起作用?
如果我用这个替换,程序将直接退出
content = this.ItemsPanel.FindName("PART_Canvas", this) as FrameworkElement;
使用FindName
,您只能找到在Template
中声明的元素。ItemsPanel
不是该模板的一部分。ItemsControl
将ItemsPanel
放入ItemsPresenter
占位符中,您可以通过该占位符访问Canvas
,但首先您需要在模板中命名ItemsPresenter
:
<ControlTemplate TargetType="{x:Type local:Viewport}">
<Border>
<ItemsPresenter x:Name="PART_ItemsPresenter"/>
</Border>
</ControlTemplate>
然后,使用VisualTreeHelper
获得Canvas
,但我认为最早可以调用下面代码的地方是FrameWorkElement
是Loaded
。这是我的例子:
public class MyListBox : ListBox
{
public MyListBox()
{
AddHandler(FrameworkElement.LoadedEvent, new RoutedEventHandler(ControlIsLoaded));
}
private void ControlIsLoaded(object sender, RoutedEventArgs e)
{
var canvas = VisualTreeHelper.GetChild(this.Template.FindName("PART_ItemsPresenter", this) as DependencyObject, 0);
}
}