[英]WPF Template.FindName return always null
模板
<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
不是該模板的一部分。 ItemsControl
提出ItemsPanel
到ItemsPresenter
占位符通過它可以訪問你的Canvas
,但首先你需要命名ItemsPresenter
在您的模板:
<ControlTemplate TargetType="{x:Type local:Viewport}">
<Border>
<ItemsPresenter x:Name="PART_ItemsPresenter"/>
</Border>
</ControlTemplate>
然后,使用VisualTreeHelper
獲取你的Canvas
,但我認為當你可以調用下面的代碼時最早的地方是FrameWorkElement
被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);
}
}
這個文檔文檔中有一個很好的例子
控件模板中的元素只有在模板應用后才可用,可以在FrameworkElement.OnApplyTemplate 方法中調用
public override void OnApplyTemplate()
{
content = this.Template.FindName("PART_Canvas", this) as FrameworkElement;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.