Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:更改ContentControl时';s内容时,新内容对象不会触发加载的事件_C#_Wpf_Datatemplate_Contentcontrol_Datatemplateselector - Fatal编程技术网

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自己触发加载的事件???