2011-06-03 10 views
5

He estado buscando en Google esto durante los últimos 2 días y no puedo llegar a ninguna parte, simplemente no puedo hacer nada con ningún control en una plantilla de datos de un tabcontrol.No puedo obtener un control de una TabControl DataTemplate

En primer lugar, el código:

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> 

En resumen esta línea:

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

lanza una "System.InvalidOperationException" Error Este operación es válido solo en los elementos que tienen esta plantilla aplicada.

esta idea en particular que recibí de here

he encontrado un montón de otras maneras de hacer esto, pero me parece que no puede llegar a ninguna parte :(espero que alguien me puede apuntar en la dirección correcta :)

+0

¿Ha intentado caminar el árbol visual en su lugar? Puedo publicar el código para hacer eso, si este es un método aceptable para usted. –

+0

¡Lo que sea que funcione! siempre que pueda acceder a myGrid puedo hacer lo que necesito :) – Julian

+0

Esto es bastante difícil de creer, no puedo encontrar el sitio en el que se está aplicando ContentTemplate ... –

Respuesta

9

Parece que es un problema con la forma en que TabControl está siendo instanciado por el tiempo de ejecución. Parece que la primera vez que se lanza el evento SelectionChanged, ContentTemplate no está listo para acceder. Si vuelve a ejecutar el código y omite el primer acceso de ContentTemplate, verá que en sucesos posteriores puede acceder a esta propiedad sin que se produzca la excepción.

A menudo estos tipos de errores se pueden solucionar llamando a Dispatcher.BeginInvoke, en este caso, permite que el tiempo de ejecución termine de inicializar el control de pestañas antes de ejecutar el código.

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); 
    })); 
+0

¡Ian, eres un genio! realmente muchas gracias! parece tener sentido, pero de todos modos esperaba que funcionara. Daría +1 pero no obtuve suficiente reputación en el momento :( – Julian

Cuestiones relacionadas