8

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;
Enzojz
  • 863
  • 2
  • 9
  • 15
  • In OnApplyTemplate method try something like content = (Canvas)GetTemplateChild("PART_Canvas") and see whether it works or not. – Sai May 30 '13 at 15:03
  • @Sai GetTemplateChild doesn't work..The canvas is in ItemsPanel I don't know how can I access it.. – Enzojz May 30 '13 at 15:14
  • @sircodesalot `This`, is a custom control derrived from ItemsControl – Enzojz May 30 '13 at 15:16

1 Answers1

11

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);
  }
}
dkozl
  • 32,814
  • 8
  • 87
  • 89
  • Hello, in my custom control, the constructor is static so I can't add 'AddHandler' in the constructor, but I put this in 'OnApplyTemplate' it works well. Thank you! – Enzojz May 31 '13 at 12:00