我知道有人问过类似的问题,作为解决方案,建议将内容包装在带有 Grid 的 DataTemplate 中并使用 Grid_Loaded 方法。但是,如果我假设我的模板选择器将根据条件一次选择 10 个 DataTemplates,那么我需要为 xaml 中的每个 DataTemplate 添加此 Grid_Loaded 事件处理程序。我正在寻找另一种不需要我重复代码的方法。
<UserControl x:Class="WHATEVER">
<UserControl.Resources>
<ResourceDictionary>
<my:DetailViewDataTemplateSelector x:Key="myDataTemplateSelector"/>
<DataTemplate x:Key="Template1">
<!-- some content -->
</DataTemplate>
<DataTemplate x:Key="Template2">
<!-- some content -->
</DataTemplate>
<DataTemplate x:Key="BlankDataTemplate" />
</ResourceDictionary>
</UserControl.Resources>
<ContentPresenter ContentTemplateSelector="{StaticResource myDataTemplateSelector}" Content="{Binding MyViewModelProperty}" />
</UserControl>
而我的模板选择器定义如下(传入的项目基本上是DataContext的MyViewModelProperty的值)
public class DetailViewDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
DataTemplate selectedTemplate = null;
if (container is FrameworkElement element)
{
selectedTemplate = element.FindResource("BlankDataTemplate") as DataTemplate;
if (item != null && item is SOME_TYPE selectedNode)
{
if (element != null && selectedNode != null)
{
if (SOME_TYPE == SOME_VALUE)
{
selectedTemplate = element.FindResource("Template1") as DataTemplate;
}
else
{
selectedTemplate = element.FindResource("Template2") as DataTemplate;
}
}
}
}
return selectedTemplate;
}
}
只是为了让您知道我尝试使用 ContentControl 而不是 ContentPresenter,甚至创建了我自己的继承自 ContentControl 的 CustomContentControl 并覆盖了 OnContentTemplateChanged 和 OnTemplateChanged 处理程序,但是每次更改 MyViewModelProperty 的值时,这些处理程序都不会被调用。
注意,调用模板选择器并根据 MyViewModelProperty 值返回正确的模板,但在选择模板后不会调用上述 OnContentTemplateChanged 和 OnTemplateChanged 处理程序。如果我有一个 Grid 作为我的 DataTemplates 中的第一个元素并订阅 Loaded 事件,那么它会在 DataTemplate 之后立即调用,因此,Grid 元素会被加载。
关于如何避免将 Loaded 处理绑定到内部网格,而不是在我们知道 ContentControl 的模板被选择器选择并加载时以某种方式触发的任何想法?提前非常感谢。