WPF Template.FindName 返回始终为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16839159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:53:43  来源:igfitidea点击:

WPF Template.FindName return always null

c#wpfxamlfindname

提问by Enzojz

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

以及 OnApplyTemplate 中的代码

content = this.Template.FindName("PART_Canvas", this) as FrameworkElement;

the content returns always null, why it doesn't work?

内容总是返回null,为什么它不起作用?

if I replace with this, the program quits directly

如果我用这个替换,程序直接退出

content = this.ItemsPanel.FindName("PART_Canvas", this) as FrameworkElement;

回答by dkozl

With FindNameyou can find only elements declared in a Template. ItemsPanelis not part of that template. ItemsControlputs ItemsPanelinto ItemsPresenterplace holder via which you can access your Canvasbut first you need to name ItemsPresenterin your template:

有了FindName你可以找到只有在一个声明的元素TemplateItemsPanel不是该模板的一部分。ItemsControlItemsPanelItemsPresenter占位通过它您可以访问Canvas,但首先你需要的名字ItemsPresenter在你的模板:

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

then, using VisualTreeHelperget your Canvas, but I think earliest place when you can call code below is when FrameWorkElementis Loaded. This is my example:

然后,使用VisualTreeHelperget your Canvas,但我认为您可以在下面调用代码的最早位置是 when FrameWorkElementis 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);
  }
}