Cant get a control from a TabControl DataTemplate
Asked Answered
U

1

5

I've been googling this for the last 2 days and cant get anywhere, I just cant do anything to any control in a datatemplate of a tabcontrol.

First off, the code:

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>

In short this line:

Grid g = tabControl1.ContentTemplate.FindName("myGrid", cp) as Grid;

throws an error "System.InvalidOperationException" This operation is valid only on elements that have this template applied.

this particular idea i got from here

I've found loads of other ways of doing this but I cant seem to get anywhere :( hope someone can point me in the right direction :)

Upholster answered 3/6, 2011 at 20:27 Comment(3)
Have you tried walking the visual tree instead? I can post code to do that, if this is an acceptable method for you.Gamogenesis
Whatever works! as long as i can get access to myGrid I can do what i need :)Upholster
This is quite a tough nut actually, cannot find the site at which the ContentTemplate is actually being applied...Ludovika
C
9

Looks like it's issue with the way the TabControl is being instantiated by the run time. It appears that the first time the SelectionChanged event is being raised the ContentTemplate is not quite ready to be accessed. If you run your code again and skip over the first access of ContentTemplate you'll see that in subsequent events you can access this property without the exception being thrown.

Often these types of errors can be overcome by calling Dispatcher.BeginInvoke, in this case it allows the run time to finish initializing the tab control before executing your code.

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);
    }));
Checky answered 4/6, 2011 at 14:5 Comment(1)
Ian, your a genius! really big thanks! it seems to make sense, but still I'd of expected it to work. i would give +1 but not got enough rep at the mo :(Upholster

© 2022 - 2024 — McMap. All rights reserved.