ItemsControl:如何在ItemsPanelTemplate中使用FindName访问面板

Cas*_*ase 3 c# wpf

<Style TargetType="{x:Type local:CustomItemsControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <ScrollViewer>
                    <ItemsPresenter x:Name="PART_Presenter"/>
                </ScrollViewer>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <StackPanel x:Name="PART_StackPanel" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

更改子级后,尝试访问StackPanel以设置事件。

[TemplatePartAttribute(Name = "PART_StackPanel", Type = typeof(StackPanel))]
[TemplatePartAttribute(Name = "PART_Presenter", Type = typeof(ItemsPresenter))]
public class CustomItemsControl: ItemsControl
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        var presenter = (ItemsPresenter)this.Template.FindName("PART_Presenter", this);
        var stackPanel = (StackPanel)this.ItemsPanel.FindName("PART_StackPanel",this);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试找到StackPanel时获取异常。

InvalidOperationException:

此操作仅对应用了此模板的元素有效。

请告知是否有办法在ItemsPanelTemplate中找到TemplatePart。我应该何时知道何时应用ItemsPanelTemplate?

Jam*_*rda 5

另一种选择是.ApplyTemplate()在仍处于ItemControl OnApplyTemplate方法中的同时调用ItemsPresenter 。然后,对的调用.FindName将成功。

    [TemplatePartAttribute(Name = "PART_StackPanel", Type = typeof(StackPanel))]
    [TemplatePartAttribute(Name = "PART_Presenter", Type = typeof(ItemsPresenter))]
    public class CustomItemsControl : ItemsControl
    {
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            var presenter = (ItemsPresenter)this.Template.FindName("PART_Presenter", this);
            presenter.ApplyTemplate();
            var stackPanel = (StackPanel)this.ItemsPanel.FindName("PART_StackPanel", presenter);
        }
    }
Run Code Online (Sandbox Code Playgroud)