[英]How to refer to the ItemsPanelTemplate from within an ItemsControl control template
[英]ItemsControl: How To Use FindName within ItemsPanelTemplate to access Panel
<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>
嘗試訪問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);
}
}
當我嘗試找到StackPanel時獲取異常。
InvalidOperationException異常:
此操作僅對應用此模板的元素有效。
請告知是否有辦法在ItemsPanelTemplate中找到TemplatePart。 什么時候我應該知道應用ItemsPanelTemplate的時間?
另一種選擇是在.ApplyTemplate()
上調用.ApplyTemplate()
,同時仍然在ItemControl的OnApplyTemplate
方法中。 然后對.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);
}
}
弄清楚Loaded事件是在ItemsPanelTemplate上等待的事件。 我能夠使用TemplatePart名稱找到StackPanel。 感謝Rick建議在Presenter中找到StackPanel。
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.Loaded += new Accordion_Loaded;
}
void Accordion_Loaded(object sender, RoutedEventArgs e)
{
var presenter = (ItemsPresenter)this.Template.FindName("PART_Presenter", this);
var stackPanel = (StackPanel)this.ItemsPanel.FindName("PART_StackPanel", presenter);
}
該FindName
方法只能發現在已經擴大,模板名稱ItemsPanel
通過擴大ItemsPresenter
,而不是ItemsControl
。 在您的情況"PART_StackPanel"
永遠是對孩子"PART_Presenter"
這樣你就可以得到這樣的一個引用:
var stackPanel = (StackPanel)VisualTreeHelper.GetChild(presenter, 0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.