Wpf 无法从TabControl数据模板获取控件

Wpf 无法从TabControl数据模板获取控件,wpf,datatemplate,tabcontrol,Wpf,Datatemplate,Tabcontrol,在过去的两天里,我一直在谷歌上搜索这个,但我什么也找不到,我就是不能对tabcontrol的数据模板中的任何控件做任何事情 首先,代码: private void Window_Loaded(object sender, RoutedEventArgs e) { tabControl1.ItemsSource = new string[] { "TabA", "TabB", "TabC" }; } private void tabControl1_SelectionChanged(ob

在过去的两天里,我一直在谷歌上搜索这个,但我什么也找不到,我就是不能对tabcontrol的数据模板中的任何控件做任何事情

首先,代码:

private void Window_Loaded(object sender, RoutedEventArgs e) {
    tabControl1.ItemsSource = new string[] { "TabA", "TabB", "TabC" };
}

private void tabControl1_SelectionChanged(object sender, SelectionChangedEventArgs e) {
    ContentPresenter cp = tabControl1.Template.FindName("PART_SelectedContentHost", tabControl1) as ContentPresenter;

    DataTemplate dt = tabControl1.ContentTemplate;
    Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;
    g.Background = new SolidColorBrush(Colors.Red);
}
xaml

抛出错误“System.InvalidOperationException”。此操作仅在应用了此模板的元素上有效

这个特别的想法是我从


我已经找到了很多其他的方法来实现这一点,但我似乎什么也做不到:(希望有人能给我指出正确的方向:)

看起来这是运行时实例化TabControl的方式的问题。第一次引发SelectionChanged事件时,ContentTemplate似乎还没有完全准备好进行访问。如果再次运行代码并跳过对ContentTemplate的第一次访问,您将看到在后续事件中,您可以访问此属性,而不会引发异常

通常,这些类型的错误可以通过调用Dispatcher.BeginInvoke来克服,在这种情况下,它允许运行时在执行代码之前完成选项卡控件的初始化

Dispatcher.BeginInvoke(new Action(() =>
    {
        ContentPresenter cp = tabControl1.Template.FindName("PART_SelectedContentHost", tabControl1) as ContentPresenter;
        Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;
        g.Background = new SolidColorBrush(Colors.Red);
    }));

你试过在视觉树上行走吗?如果这对你来说是一个可以接受的方法,我可以发布代码来做这件事。不管什么都可以!只要我可以访问myGrid,我就可以做我需要的:)这是一个相当棘手的问题,实际上,找不到ContentTemplate实际应用的站点……伊恩,你真是个天才!非常感谢!这似乎有道理,但我还是希望它能起作用。我会给+1,但在任务单上没有得到足够的代表:(
Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;
Dispatcher.BeginInvoke(new Action(() =>
    {
        ContentPresenter cp = tabControl1.Template.FindName("PART_SelectedContentHost", tabControl1) as ContentPresenter;
        Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;
        g.Background = new SolidColorBrush(Colors.Red);
    }));