How to get DataGrid object of TabControl.ContentTemplate

Lê quang Thắng 20 Reputation points
2024-12-11T05:02:59.11+00:00

Dear all,

I have a control using ContentTemplate and i would like to binding the Visibility properties with viewModel but that error 'Cannot find governing FrameworkElement or FrameworkContentElement for target element'. This is control in xaml:
<TabControl x:Name="tabControlMain" TabStripPlacement="Top" ItemsSource="{Binding TabItems, Mode=TwoWay}" SelectedIndex="{Binding SelectedAddressIndex, Mode=TwoWay}" FontSize="18" SelectionChanged="TabControl_SelectionChanged">

            <TabControl.ItemTemplate>

                <DataTemplate>

                    <Grid>

                        <Grid.RowDefinitions>

                            <RowDefinition Height="auto"/>

                            <RowDefinition Height="auto"/>

                            <RowDefinition Height="auto"/>

                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="auto"/>

                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding AddressDevice, Mode=TwoWay}"/>

                    </Grid>

                </DataTemplate>

            </TabControl.ItemTemplate>

            <TabControl.ContentTemplate>

                <DataTemplate>

                    <!-- your tab content here -->

                    <Grid x:Name="grid">

                        <Grid.RowDefinitions>

                            <RowDefinition Height="auto"/>

                            <RowDefinition Height="auto"/>

                            <RowDefinition Height="auto"/>

                            <RowDefinition Height="*"/>

                            <RowDefinition Height="auto"/>

                            <RowDefinition Height="auto"/>

                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="auto"/>

                            <ColumnDefinition Width="*"/>

                            <ColumnDefinition Width="auto"/>

                            <ColumnDefinition Width="*"/>

                        </Grid.ColumnDefinitions>

                        <Label Grid.Row="0" Grid.Column="0" Content="Items Name:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" FontWeight="Bold"/>

                        <Label Grid.Row="0" Grid.Column="1" Margin="5,5,5,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" Background="#FFDBFFFB" Content="{Binding ItemName}"/>

                        <Label Grid.Row="0" Grid.Column="2" Content="BMS Type:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" FontWeight="Bold"/>

                        <Label Grid.Row="0" Grid.Column="3" Content="{Binding BMSType, Mode=TwoWay}" Margin="5,5,5,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" Background="#FFDBFFFB"/>

                        <Label Grid.Row="1" Grid.Column="0" Content="Test Time:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" FontWeight="Bold"/>

                        <Label Grid.Row="1" Grid.Column="1" Content="{Binding TestTime, Mode=TwoWay}" Margin="5,5,5,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" Background="#FFDBFFFB"/>

                        <Label Grid.Row="1" Grid.Column="2" Content="Other:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" FontWeight="Bold"/>

                        <Label Grid.Row="1" Grid.Column="3" Content="" Margin="5,5,5,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" Background="#FFDBFFFB"/>

                        <Label Grid.Row="2" Grid.Column="0" Content="Test Barcode:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" FontWeight="Bold"/>

                        <Label Grid.Row="2" Grid.Column="1" Content="{Binding TestBarcode, Mode=TwoWay}" Margin="5,5,5,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="1" Grid.RowSpan="1" Background="#FFDBFFFB"/>

                        <Grid Grid.Row="3" Grid.ColumnSpan="4" Margin="10,10,10,0">

                            <Grid.RowDefinitions>

                                <RowDefinition Height="*"/>

                                <RowDefinition Height="auto"/>

                            </Grid.RowDefinitions>

                            <Grid.ColumnDefinitions>

                                <ColumnDefinition Width="*"/>

                            </Grid.ColumnDefinitions>

                            <ScrollViewer Grid.Row="0" Grid.Column="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">

                                <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" CanUserAddRows="False" ItemsSource="{Binding TestData, Mode=TwoWay}">

                                    <DataGrid.Columns>

                                        <DataGridTextColumn Header="Test Item" Binding="{Binding TestItem, Mode=TwoWay}">

                                            <DataGridTextColumn.CellStyle>

                                                <Style TargetType="DataGridCell">

                                                    <Setter Property="FontSize" Value="12"/>

                                                    <!-- Set Font Size -->

                                                    <Setter Property="FontWeight" Value="Bold"/>

                                                    <!-- Set Bold Font -->

                                                </Style>

                                            </DataGridTextColumn.CellStyle>

                                        </DataGridTextColumn>

                                        <DataGridTextColumn Header="B1" Binding="{Binding B1, Mode=TwoWay}" Width="80" Visibility="{Binding EnableB1}"/>

                                    </DataGrid.Columns>

                                </DataGrid>

                            </ScrollViewer>

                            <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal">

                                <Label Content="Test results:" BorderBrush="#FFBBBBBB" FontWeight ="Bold"/>

                                <Label Content="{Binding TestResult, Mode=TwoWay}" BorderBrush="#FFBBBBBB"/>

                            </StackPanel>

                        </Grid>

                        <ProgressBar x:Name="MyProgressBar" Value="{Binding ProcessTestValue, Mode=TwoWay}" Grid.Row="4" HorizontalAlignment="Stretch" Margin="5,6,5,0" Grid.ColumnSpan="4" VerticalAlignment="Stretch" Background="White" BorderBrush="#FF717171" Height="30"/>

                        <TextBlock Grid.Row="4" Margin="5,6,5,0" Grid.ColumnSpan="4" Text="{Binding ElementName=MyProgressBar, Mode=TwoWay, Path=Value, StringFormat='{}{0:F0} %'}" FontSize="20" 

                               HorizontalAlignment="Center" 

                               VerticalAlignment="Center" Foreground="Black" FontWeight="Bold"/>

                        <Label Grid.Row="5" Grid.ColumnSpan="4" Content="{Binding TestTime, Mode=TwoWay}" HorizontalAlignment="Stretch" Margin="5,10,5,10" VerticalAlignment="Stretch" Background="#FFDBFFFB" Height="50" FontSize="20" FontWeight="Bold" Foreground="Red">

                        </Label>

                    </Grid>

                </DataTemplate>

            </TabControl.ContentTemplate>

        </TabControl>  

How to binding Visibility to EnableB1 and get object named 'dataGrid' from tabControlMain?
Thanks!

.NET
.NET
Microsoft Technologies based on the .NET software framework.
4,007 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,804 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
824 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hongrui Yu-MSFT 3,645 Reputation points Microsoft Vendor
    2024-12-11T09:45:24.1966667+00:00

    Hi, @Lê quang Thắng. Welcome to Microsoft Q&A. 

    Solution: 1.Define DataGrid in Resource and use ContentPresenter to present DataGrid. In the code, use this.Resources["dataGrid"] as DataGrid; to directly obtain DataGrid.

    2.Define DataContext in "Resource" and bind it directly through "Visibility="{Binding Path=EnableB1,Source={StaticResource MyMainWindowViewModel},Mode=TwoWay}"

    Here we assume that your ViewModel is MainWindowViewModel.

    MainWindow.xaml

    <Window.Resources>
        <vm:MainWindowViewModel x:Key="MyMainWindowViewModel" x:Name="MyMainWindowViewModel"></vm:MainWindowViewModel>
        <DataGrid x:Key="dataGrid" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Test Item" Binding="{Binding TestItem, Mode=TwoWay}">
                    <DataGridTextColumn.CellStyle>
                        <Style TargetType="DataGridCell">
                            <Setter Property="FontSize" Value="12"/>
                            <!--Set Font Size-->
                            <Setter Property="FontWeight" Value="Bold"/>
                            <!--Set Bold Font-->
                        </Style>
                    </DataGridTextColumn.CellStyle>
                </DataGridTextColumn>
                <DataGridTextColumn Header="B1" Binding="{Binding B1, Mode=TwoWay}" Width="80" Visibility="{Binding Path=EnableB1,Source={StaticResource MyMainWindowViewModel},Mode=TwoWay}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Window.Resources>
    <Grid>
        <TabControl x:Name="tabControlMain" >
    	…
                            <ScrollViewer Grid.Row="0" Grid.Column="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                                <ContentPresenter Content="{DynamicResource dataGrid}" ></ContentPresenter>
                            </ScrollViewer>
    		…
        </TabControl>
    </Grid>
    

    MainWindow.xaml.cs

        public partial class MainWindow : Window
        {
            public MainWindowViewModel mainWindowViewModel; 
            public MainWindow()
            {
                InitializeComponent();
    			//Note that `DataContext` should use the same
                mainWindowViewModel = this.Resources["MyMainWindowViewModel"] as MainWindowViewModel;
                tabControlMain.DataContext = mainWindowViewModel;
    			// Get directly to dataGrid
                var dataGrid = this.Resources["dataGrid"] as DataGrid;
                dataGrid.DataContext = mainWindowViewModel;
                dataGrid.ItemsSource = mainWindowViewModel.TestData;
            }
        }
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.