GetTemplateChild 在不同的项目中返回 null
本文关键字:返回 null 项目 GetTemplateChild | 更新日期: 2023-09-27 18:32:56
我创建了一个派生自标准WPF comboBox
的FilteredComboBox
。到目前为止,这个新UserControl
在设计它的原始测试应用程序中运行良好。现在我已经将类复制到我的主应用程序,我在尝试访问ComboBox
的PART_EditableTextBox
子级时出现空引用异常:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
EditableTextBox.SelectionChanged += EditableTextBox_SelectionChanged;
ItemsPopup.Focusable = true;
}
private TextBox EditableTextBox
{
get { return (TextBox)GetTemplateChild("PART_EditableTextBox"); }
}
问题出现在我要添加SelectionChanged
事件的行中。在进行一些研究时,总是建议等到ApplyTemplate
完成,这基本上是在base.OnApplyTemplate();
我在主应用程序中检查了底层模板,它应该包含PART_EditableTextBox
。
关于这里可能出现的问题或我可以做些什么进行进一步调查的任何想法?
更新:我在检查了泽维尔的一些建议后发现了问题。PART_EditableTextBox的问题在于,它仅在组合框定义为
IsEditable = True
我不得不承认,在我提到的第二个项目中,情况并非如此。如果组合框不可编辑,那么它根本没有可编辑文本框:-/
感谢大家的支持...
您应该验证是否正在获取所需的模板。如果您确定模板具有所需的命名部件,但尝试检索它返回 null,则当您尝试访问它时,几乎可以肯定它不会应用于控件。
您提到,当您将控件从一个程序集移动到另一个程序集时,问题就开始了。也许您将其移动到的程序集未正确设置以执行您尝试执行的操作。
例如,您是否希望模板作为默认主题的一部分自动应用?如果是这样,样式是否位于程序集中的正确位置(在 themes/generic.xaml 中或从中引用(,您是否在 AssemblyInfo.cs 文件中正确定义了 ThemeInfo 属性?(此外,是否重写用户控件中的元数据以使用正确的资源键?
如果您改为在某处显式应用模板,那么基类中的默认值可能会在您的之前应用,因此您在应用默认值时会崩溃,并且永远不会达到应用您的模板的点。
有几件事可能是错误的,如果不简单地检查所有内容,就很难知道是哪件事。希望我说的话能给你一个关于这个问题的提示。
注意:在实践中,我总是在尝试检索模板部分后添加空检查。您永远无法确定如何使用控件,以及可以在不同方案中应用哪些模板。例如,使用该控件的任何人都可以重写模板,而不必指定所需的部件。在我看来,最好让控件不按设计运行,而不是使应用程序崩溃。
注意 2:与其让属性在每次要访问模板部件时都查找它,不如在 OnApplyTemplate 中查找一次,并将其存储为成员变量。这将在每次从代码访问控件时保存模板查找。
您是否考虑过将其设置为自定义控件而不是用户控件?我认为您面临的问题可能是由于在对象生命周期中初始化UserControl的时间
。在下面的示例中,您尝试在部件可访问之前连接事件处理程序。
解决此类问题的一种方法是使用调度程序等到安全后再连接事件处理程序。
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
GetTemplateParts();
ItemsPopup.Focusable = true;
}
protected void GetTemplateParts()
{
Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Loaded,
new Action(() =>
{
EditableTextBox.SelectionChanged += EditableTextBox_SelectionChanged;
}));
}