Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Template.FindName return always null

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;
like image 408
Enzojz Avatar asked May 30 '13 14:05

Enzojz


1 Answers

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);
  }
}
like image 141
dkozl Avatar answered Oct 14 '22 05:10

dkozl