0

Basic concept would be, when user presses start button and a new list comes back from worker thread, it'd be added to a "list of lists" than would be showed up in a newly created tabitem. However I cannot seem to grab the datagrid on the newly created tabitem.....still could not figured out, FindName and whatever methods was tried

XAML

<TabControl x:Name="tabMain" Margin="8,63,10,10" IsSynchronizedWithCurrentItem="True" >
    <TabControl.ContentTemplate>
        <DataTemplate>
            <Grid x:Name="grMain" Background="#FFE5E5E5">
                <DataGrid x:Name="dgResults" IsReadOnly="True" AutoGenerateColumns="False" AlternatingRowBackground="#FFAAE8D5" ItemsSource="{Binding data}" >
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="Key" Binding="{Binding col1}" Width="150">
                            <DataGridTextColumn.ElementStyle>
                                <Style>
                                    <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                        <DataGridTextColumn Header="Value" Binding="{Binding col2}" Width="*">
                            <DataGridTextColumn.ElementStyle>
                                <Style>
                                    <Setter Property="TextBlock.TextWrapping" Value="Wrap" />

                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                    </DataGrid.Columns>
                </DataGrid>

            </Grid>

        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl >

CODE after getting the list

lstFinal.Add(e.Result as List<Col1Col2>);
TabItem newtab = new TabItem();
newtab.DataContext = lstFinal[lstFinal.Count - 1];


newtab.Header = txtMaterial.Text;
tabMain.Items.Add(newtab);
tabMain.SelectedIndex = tabMain.Items.Count - 1;
DataGrid dg = newtab.FindName("dgResults") as DataGrid;
dg.ItemsSource = lstFinal[lstFinal.Count - 1];
RubberDuck
  • 11,933
  • 4
  • 50
  • 95
gericooper
  • 242
  • 2
  • 11
  • yes that is my problem dg is null (not found). list isfine, only dg is the problem – gericooper Sep 04 '14 at 09:23
  • When you post a question, then it is of utmost importance to describe what exactly is going wrong - http://meta.stackoverflow.com/questions/260648/stack-overflow-question-checklist. In your situation I would have tried to solve everything on ViewModel side, http://msdn.microsoft.com/en-us/magazine/dd419663.aspx is a slightly old, but nonetheless solid article on MVVM that actively uses TabItems. – Eugene Podskal Sep 04 '14 at 09:38
  • I am barely familiar with exact mechanics of `FindName` and its use with template, so I could only recommend you to try classic way of searching with `LogicalTreeHelper` - http://stackoverflow.com/questions/636383/how-can-i-find-wpf-controls-by-name-or-type. Also, read http://stackoverflow.com/questions/16101411/find-children-of-a-user-control-in-a-tab-item. – Eugene Podskal Sep 04 '14 at 09:38
  • @EugenePodskal, while I would normally agree with your sentiments, in this case, or any case where a question author says that they can't access a `DataTemplate` generated control, the solution is fairly obvious and straight forward and it is unnecessary to provide further information. However, your recommendation of using the `LogicalTreeHelper` was correct. – Sheridan Sep 04 '14 at 09:44

1 Answers1

0

Your problem is caused because you are trying to reference a control from within a DataTemplate. At run time, this template may have been applied to a large number of controls, so first you have to get the object that had the template applied and then you can access the control from the DataTemplate.

You can find out exactly how to do that by referring to the How to: Find DataTemplate-Generated Elements page on MSDN. However, in short, this is how it's done (from the linked page):

// Getting the currently selected ListBoxItem 
// Note that the ListBox must have 
// IsSynchronizedWithCurrentItem set to True for this to work
ListBoxItem myListBoxItem =
    (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));

// Getting the ContentPresenter of myListBoxItem
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);

// Finding textBlock from the DataTemplate that is set on that ContentPresenter
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);

// Do something to the DataTemplate-generated TextBlock
MessageBox.Show("The text of the TextBlock of the selected list item: "
    + myTextBlock.Text);

The definition of the FindVisualChild method can also be found on the linked page, along with a description of the process.

Sheridan
  • 68,826
  • 24
  • 143
  • 183