C# WPF:更改ContentControl时';s内容时,新内容对象不会触发加载的事件
问题:C# WPF:更改ContentControl时';s内容时,新内容对象不会触发加载的事件,c#,wpf,datatemplate,contentcontrol,datatemplateselector,C#,Wpf,Datatemplate,Contentcontrol,Datatemplateselector,问题: <controls:KeyboardHost Grid.Row="0" ContentTemplateSelector="{StaticResource KeyboardDataTemplateSelector}"> <ContentControl.Content> <MultiBinding Converter="{StaticResource KeyboardCriteriaValu
<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>
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的内容后,我无法连接到时间点,已应用DataTemplateSelector中的DataTemplate,并且已完成所有可视化布局,即加载新内容
设置:
<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>
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
}
}
一个名为“KeyboardHost”的自定义控件,它扩展了ContentControl
ContentControl.Content通过值转换器绑定(使用多重绑定)到2个通知属性,该值转换器将2个绑定属性组合到“KeyboardCriteria”类型的对象中
“KeyboardCriteria”是一个公共类,但我也尝试将其设置为FrameworkElement、Control和UserControl,以便尝试挂接到初始化、加载的etc事件中
ContentControl.ContentTemplateSelector是一个自定义选择器类(如下),它返回
基于ContentControl.Content(“KeyboardCriteria”)的数据模板
ContentControl.ContentTemplateSelector的DataTemplates是选择器上的属性,在my 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>
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事件:
Initialized
Loaded
OnContentChanged
OnContentTemplateChanged
我已附加/覆盖以下“KeyboardCriteria”(定义为FrameworkElement)事件:
观察结果:
<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>
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
}
}
启动时:
KeyboardHost: OnTemplateChanged
KeyboardHost: ContentChanged
KeyboardCriteria: Initialized
KeyboardCriteria: Loaded
更改某个绑定条件属性(从而创建新的KeyboardCriteria对象)时:
注意:ContentControl.Content对象(“KeyboardCriteria”)上缺少加载的事件。
下一步:
<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>
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
}
}
我想我会完全放弃使用DataTemplateSelector的想法,将选择逻辑构建到ContentControl中,因为这已经是一个CustomControl了。我希望通过手动创建内容(并填充内容),可以避免使用当前在选择逻辑中使用的数据模板,因为我怀疑这是问题的一部分
代码示例:
<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>
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
}
}
MainViewModel:
<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>
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
}
}
公开最初具有非空值的“键盘”属性
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>
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
}
}
键盘数据模板选择器:
<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>
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的内容后,我将执行以下操作:
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)OnAfterRendered);
然后,在“OnAfterRendered”方法中,我可以使用带有应用数据模板的ContentControl抱歉,我没有阅读整篇文章,因为我现在没有足够的时间/注意力阅读它,但是当它加载时,
ContentControl
只会启动一次Loaded
。我发现,当您将某个内容绑定到内容时,DataContextChanged
事件将在绑定到内容的对象更改时触发(并触发通知)。我很高兴ContentControl的Loaded事件不会在内容更改时触发,但我正在尝试获取内容的Loaded事件。ContentControl.ContentChanged持续激发,因此我知道内容何时发生更改,但我很难知道新内容何时加载。我需要知道布局过程何时完成,因为我的下一步是根据新内容及其子元素的呈现位置创建一组坐标。如果我将方法更改为不使用数据模板和内容数据模板选择器(即,创建内容控件并将其设置为自己的内容属性的内容控件)然后,新的content属性正确地触发加载的事件。我认为最初的问题与内容不是可视化树的一部分有关,即KeyboardCriteria是模板化的,永远不会出现在可视化树本身中,因此永远不会触发加载的事件。我猜它是初始化的,然后模板化,然后模板化元素ENT自己触发加载的事件???