Template
<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>
And the code in OnApplyTemplate
content = this.Template.FindName("PART_Canvas", this) as FrameworkElement;
the content returns always null, why it doesn't work?
if I replace with this, the program quits directly
content = this.ItemsPanel.FindName("PART_Canvas", this) as FrameworkElement;
With FindName
you can find only elements declared in a Template
. ItemsPanel
is not part of that template. ItemsControl
puts ItemsPanel
into ItemsPresenter
place holder via which you can access your Canvas
but first you need to name ItemsPresenter
in your template:
<ControlTemplate TargetType="{x:Type local:Viewport}">
<Border>
<ItemsPresenter x:Name="PART_ItemsPresenter"/>
</Border>
</ControlTemplate>
then, using VisualTreeHelper
get your Canvas
, but I think earliest place when you can call code below is when FrameWorkElement
is Loaded
. This is my example:
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);
}
}