我有一个 UserControl(不是一个不起眼的自定义控件),它根据一些自定义状态属性交换各种 ContentTemplates,所有内容都定义为关联 XAML 文件中的资源。在代码隐藏中,我需要在换入的 ContentTemplates 中找到其中一个元素。
现在在一个无外观的控件(即自定义控件)中,您只需覆盖 OnApplyTemplate 然后使用 FindName,但是当 ContentTemplate 被触发器切换时,该覆盖不会触发(......至少对于 UserControl 而言不是。我没有使用自定义控件测试了该功能。)
现在我尝试将 Loaded 事件连接到交换模板中的控件,该模板在代码隐藏中触发,然后我只需将“发送者”存储在类级变量中。但是,当我尝试通过订阅 Unloaded 事件来清除该值时,它也不会触发,因为模板被换出,因此在它有机会被调用之前取消连接该事件并且控件从屏幕上静默卸载,但我在代码隐藏中仍然有那个挂起的引用。
为了模拟 OnApplyTemplate 功能,我正在考虑订阅 ContentTemplateChanged 通知并仅使用 VisualTreeHelper 来查找我想要的控件,但我想知道是否有更好的方法,因此这篇文章。
有任何想法吗?
作为参考,这是我拥有的控件的一个非常精简的示例。在这个例子中,如果 IsEditing 为真,我想找到名为“FindMe”的文本框。如果 IsEditing 为 false,这意味着 ContentTemplate 没有被交换,我想得到'null'......
<UserControl x:Class="Crestron.Tools.ProgramDesigner.Controls.EditableTextBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Crestron.Tools.ProgramDesigner.Controls"
x:Name="Root">
<UserControl.Resources>
<DataTemplate x:Key="EditModeTemplate">
<TextBox x:Name="FindMe"
Text="{Binding Text, ElementName=Root}" />
</DataTemplate>
<Style TargetType="{x:Type local:EditableTextBlock}">
<Style.Triggers>
<Trigger Property="IsEditing" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource EditModeTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<TextBlock x:Name="TextBlock"
Text="{Binding Text, ElementName=Root}" />
</UserControl>
啊啊啊,去吧!
米