WPF Template.FindName返回始终为null

时间:2013-05-30 14:42:57

标签: c# wpf xaml findname

模板

<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;

1 个答案:

答案 0 :(得分:10)

使用FindName,您只能找到Template中声明的元素。 ItemsPanel不是该模板的一部分。 ItemsControlItemsPanel放入ItemsPresenter占位符中,您可以通过该Canvas来访问ItemsPresenter,但首先您需要在模板中命名<ControlTemplate TargetType="{x:Type local:Viewport}"> <Border> <ItemsPresenter x:Name="PART_ItemsPresenter"/> </Border> </ControlTemplate>

VisualTreeHelper

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

{{1}}