问题:
我无法在更改ContentControl内容后,DataTemplateSelector应用DataTemplate并完成所有可视化布局之后,即新内容已加载之后的时间点挂钩。
设置:
一个名为“KeyboardHost”的自定义控件,它扩展了ContentControl。
ContentControl.Content通过多绑定绑定到2个通知属性,使用值转换器将这两个绑定属性组合成类型为“KeyboardCriteria”的对象。
'KeyboardCriteria'是一个公共类,但我还尝试将其制作为FrameworkElement、Control和UserControl,以便尝试挂钩Initialized、Loaded等事件。
ContentControl.ContentTemplateSelector是一个自定义选择器类(下面),它根据ContentControl.Content('KeyboardCriteria')返回DataTemplate。
ContentControl.ContentTemplateSelector的DataTemplates是选择器上的属性,并在我的MainView的资源部分中初始化和分配。
尝试:
我已经附加/覆盖了以下ContentControl事件:
Initialized
Loaded
OnContentChanged
OnContentTemplateChanged
我已经连接/覆盖了以下'KeyboardCriteria'(定义为FrameworkElement)事件:
Initialized
Loaded
OnApplyTemplate
OnTemplateChanged
TemplateDP callback
观察结果:
启动时:
KeyboardHost: OnTemplateChanged
KeyboardHost: ContentChanged
KeyboardCriteria: Initialized
KeyboardCriteria: Loaded
更改其中一个绑定条件属性(从而创建一个新的KeyboardCriteria对象)时:
KeyboardHost: ContentChanged
KeyboardCriteria: Initialized
注意:ContentControl.Content对象('KeyboardCriteria')缺少Loaded事件。
下一步:
我认为我会完全放弃使用DataTemplateSelector的想法,并将选择逻辑构建到我的ContentControl中,因为这已经是一个CustomControl。我希望通过手动创建内容(并填充它),可以避免在选择逻辑中使用当前使用的DataTemplates,因为我怀疑这是问题的一部分。
...
代码示例:
MainViewModel:
公开“Keyboard”属性,该属性最初具有非空值。
MainView:
<controls:KeyboardHost Grid.Row="0"
ContentTemplateSelector="{StaticResource KeyboardDataTemplateSelector}">
<ContentControl.Content>
<MultiBinding Converter="{StaticResource KeyboardCriteriaValueConverter}" Mode="OneWay">
<Binding Source="{x:Static properties:Settings.Default}" Path="Language" />
<Binding Path="Keyboard" />
</MultiBinding>
</ContentControl.Content>
</controls:KeyboardHost>
KeyboardCriteriaValueConverter:
仅包含Convert方法,ConvertBack未实现。
为简化逻辑,已移除检查值类型、计数等的额外逻辑。
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return new KeyboardCriteria
{
Language = values[0],
Keyboard = values[1]
};
}
KeyboardDataTemplateSelector:
public class KeyboardDataTemplateSelector : DataTemplateSelector
{
//TEMPLATE PROPERTIES HERE - THESE ARE SET IN THE RESOURCE DEFINITION
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var criteria = item as KeyboardCriteria;
//LOGIC TO RETURN THE APPROPRIATE KEYBOARD DATA TEMPLATE BASED ON THE criteria
}
}
感谢您能提供的任何见解。
谢谢。
ContentControl
仅在其Loaded
时触发一次。 我发现当你将某些东西绑定到Content
时,当绑定到内容的对象更改(并触发通知)时,DataContextChanged
事件将被触发。 - Kcvin