无法从TabControl DataTemplate中获取控件

5

我已经谷歌了两天,但一无所获。我无法对TabControl的DataTemplate中的任何控件进行操作。

首先,是代码:

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

<Window x:Class="tabTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
    <TabControl IsSynchronizedWithCurrentItem="True" Height="140" Name="tabControl1" Width="230" SelectionChanged="tabControl1_SelectionChanged">
        <TabControl.ContentTemplate>
            <DataTemplate>
                <Grid x:Name="myGrid">                        
                </Grid>
            </DataTemplate>    
        </TabControl.ContentTemplate>            
    </TabControl>
</Grid>

简而言之,这行代码的意思是:
Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;

抛出错误“System.InvalidOperationException”,此操作仅适用于具有此模板的元素。

我从这里得到了这个特定的想法。

我找到了很多其他方法来做这件事,但似乎一无所获:( 希望有人能指点我正确的方向:)


你尝试过遍历可视化树吗?如果这是一种可接受的方法,我可以发布代码来实现它。 - Ed Bayiates
无论怎样都可以!只要我能访问到myGrid,我就能做我需要做的 :) - Julian
实际上这是一个相当棘手的问题,无法找到ContentTemplate实际应用的站点... - H.B.
1个回答

9
看起来这是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);
    }));

Ian,你真是个天才!非常感谢!看起来很有道理,但我本以为它会起作用。我想给+1,但目前声望不够:( - Julian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接