模板

<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不属于该模板。 ItemsControlItemsPanel放入ItemsPresenter占位符,您可以通过该占位符访问Canvas,但首先需要在模板中命名ItemsPresenter:

<ControlTemplate TargetType="{x:Type local:Viewport}">
   <Border>
      <ItemsPresenter x:Name="PART_ItemsPresenter"/>
   </Border>
</ControlTemplate>

然后,使用VisualTreeHelper获取您的Canvas,但是我认为最早可以调用以下代码的地方是当FrameWorkElementLoaded时。这是我的示例:
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);
  }
}

关于c# - WPF Template.FindName返回始终为null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16839159/

10-11 12:24