简体   繁体   English

WPF:更改ContentControl的Content时,新的content对象不会触发加载的事件

[英]WPF: When changing a ContentControl's Content, the new content object is NOT firing the loaded event

Problem: 问题:

I am unable to hook into the point in time after I change a ContentControl's content, the DataTemplate from a DataTemplateSelector has been applied, and all visual layout has been completed, ie the new content is Loaded. 在更改ContentControl的内容,应用DataTemplateSelector中的DataTemplate以及完成所有视觉布局(即已加载新内容)之后,我无法及时了解到这一点。

Setup: 设定:

A custom control called 'KeyboardHost' which extends a ContentControl . 一个自定义控件,称为“ KeyboardHost” ,它扩展了ContentControl

ContentControl.Content is bound (using a multi-binding) to 2 notification properties, via a value converter which combines the 2 bound properties into an object of type 'KeyboardCriteria'. ContentControl.Content通过一个值转换器(使用多重绑定)绑定到2个通知属性,该值转换器将2个绑定的属性组合到类型为'KeyboardCriteria'的对象中。

'KeyboardCriteria' is a public class, but I have also tried making this a FrameworkElement, Control and UserControl so that I could try to hook into the Initialized, Loaded etc events. “ KeyboardCriteria”是一个公共类,但我也尝试将其设置为FrameworkElement,Control和UserControl,以便尝试连接Initialized,Loaded等事件。

ContentControl.ContentTemplateSelector is a custom selector class (below) which returns a DataTemplate based on the ContentControl.Content (the 'KeyboardCriteria'). ContentControl.ContentTemplateSelector是一个自定义选择器类(如下),它基于ContentControl.Content(“ KeyboardCriteria”)返回一个DataTemplate。

The ContentControl.ContentTemplateSelector's DataTemplates are properties on the selector and are initialised and assigned in the resources section of my MainView. ContentControl.ContentTemplateSelector的DataTemplates是选择器上的属性,并在MainView的资源部分中初始化和分配。

Attempts: 尝试:

I have attached/overridden the following ContentControl events: 我已附加/覆盖了以下ContentControl事件:

Initialized

Loaded

OnContentChanged

OnContentTemplateChanged

I have attached/override the following 'KeyboardCriteria' (defined as a FrameworkElement) events: 我已附加/覆盖以下“ KeyboardCriteria”(定义为FrameworkElement)事件:

Initialized

Loaded

OnApplyTemplate

OnTemplateChanged

TemplateDP callback

Observations: 观察:

On startup: 启动时:

KeyboardHost: OnTemplateChanged

KeyboardHost: ContentChanged

KeyboardCriteria: Initialized

KeyboardCriteria: Loaded

When changing one of the bound criteria properties (thus creating a new KeyboardCriteria object): 更改绑定条件属性之一(从而创建一个新的KeyboardCriteria对象)时:

KeyboardHost: ContentChanged

KeyboardCriteria: Initialized

NB The lack of a Loaded event on the ContentControl.Content object (the 'KeyboardCriteria'). 注意:ContentControl.Content对象(“ KeyboardCriteria”)上缺少Loaded事件。

Next steps: 下一步:

I think I will scrap the idea of using a DataTemplateSelector entirely and build the selection logic into my ContentControl, as this is already a CustomControl. 我想我将完全放弃使用DataTemplateSelector的想法,并将选择逻辑构建到我的ContentControl中,因为这已经是一个CustomControl。 I am hoping by manually creating the Content (and populating it) I can avoid the use of the DataTemplates that I currently use in the selection logic, as I suspect this is part of the problem. 我希望通过手动创建内容(并填充内容)来避免使用选择逻辑中当前使用的DataTemplates,因为我怀疑这是问题的一部分。

... ...

CODE SAMPLES: 代码示例:

MainViewModel: MainViewModel:

Exposes 'Keyboard' property, which initially has a non-null value. 公开“键盘”属性,该属性最初具有非空值。

MainView: 的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: KeyboardCriteriaValueConverter:

Convert method only, ConvertBack throws NotImplementedException. 仅限于Convert方法,ConvertBack引发NotImplementedException。

Logic has been simplified to remove extra logic to check value types, count, etc. 逻辑已简化,删除了检查值类型,计数等的额外逻辑。

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    return new KeyboardCriteria
    {
        Language = values[0], 
        Keyboard = values[1]
    };
}

KeyboardDataTemplateSelector: 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
    }
}

Thanks for any insight you can provide. 感谢您提供的任何见解。

I know this is an old thread, but I recently stumbled over the same problem. 我知道这是一个旧线程,但是最近我偶然发现了同样的问题。 Here is what I did, to solve it, in case someone else can use it. 如果别人可以使用它,这是我为解决此问题所做的工作。

After I set the Content of ContentControl i do the following: 设置ContentControl的内容后,请执行以下操作:

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)OnAfterRendered);

Then in the "OnAfterRendered" method i can work with the ContentControl with applied DataTemplates 然后在“ OnAfterRendered”方法中,我可以使用带有已应用数据模板的ContentControl

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM