Search code examples
c#wpfado.netwpf-controlswpfdatagrid

how to move from one tabitem to another in WPF


I have a tab-control with three tab items. each tab item has a datagrid placed on it. and all these three datagrid's on their respective tab items is of Master-Detail-SubDetail form.

how to move from first tab item to the second tab item when a user selects a row on the Master datagrid? I have created a Model using ADO.Net entity framework to create this master-detail view.

XAML layout

 <TabControl Height="270" HorizontalAlignment="Left" Margin="16,23,0,0" Name="tabControl1" VerticalAlignment="Top" Width="462">
        <TabItem Header="Person" Name="tabItem1">
            <Grid DataContext="{StaticResource peopleViewSource}">
                <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="166" SelectedItem="{Binding personDetails}"
                          HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="64,23,0,0" Name="peopleDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="289">
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="personIDColumn" Binding="{Binding Path=personID}" Header="person ID" Width="SizeToHeader" />
                        <DataGridTextColumn x:Name="firstNameColumn" Binding="{Binding Path=firstName}" Header="first Name" Width="SizeToHeader" />
                        <DataGridTextColumn x:Name="lastNameColumn" Binding="{Binding Path=lastName}" Header="last Name" Width="SizeToHeader" />
                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
        </TabItem>
        <TabItem Header="Person Details" Name="tabItem2">
            <Grid DataContext="{StaticResource peoplepersonDetailsViewSource}">
                <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="120" SelectedItem="{Binding personDetails.personStatus}"
                          HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="82,18,0,0" Name="personDetailsDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="172">
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="detailIDColumn" Binding="{Binding Path=detailID}" Header="detail ID" Width="SizeToHeader" />
                        <DataGridTextColumn x:Name="positionColumn" Binding="{Binding Path=position}" Header="position" Width="SizeToHeader" />
                        <DataGridTextColumn x:Name="personIDColumn1" Binding="{Binding Path=personID}" Header="person ID" Width="SizeToHeader" />
                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
        </TabItem>
        <TabItem Header="Person Status" Name="tabItem3">
            <Grid DataContext="{StaticResource peoplepersonDetailspersonStatusViewSource}">
                <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="143" HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="91,23,0,0" Name="personStatusDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="185">
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="detailIDColumn1" Binding="{Binding Path=detailID}" Header="detail ID" Width="SizeToHeader" />
                        <DataGridTextColumn x:Name="positionColumn1" Binding="{Binding Path=position}" Header="position" Width="SizeToHeader" />
                        <DataGridTextColumn x:Name="statussColumn" Binding="{Binding Path=statuss}" Header="statuss" Width="SizeToHeader" />
                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
        </TabItem>
    </TabControl>

tab item 1

tab item 2


Solution

  • You could setup a EventTrigger on the DataGrid SelectionChanged event

    Because EventTrigger only allowa Animation you can setup a Int32AnimationUsingKeyFrames animation to change the TabControl SelectedIndex

    Trigger

     <DataGrid.Triggers>
        <EventTrigger RoutedEvent="DataGrid.SelectionChanged" > // SelectionChanged Event
            <BeginStoryboard>
                <Storyboard >
                    <Int32AnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="tabControl1" Storyboard.TargetProperty="SelectedIndex"> // set target control and target property
                        <SplineInt32KeyFrame KeyTime="00:00:00" Value="1"/> // Value = TabControl Selected index you want to show
                    </Int32AnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </DataGrid.Triggers>
    

    Here is an example:

    <TabControl Height="270" HorizontalAlignment="Left" Margin="16,23,0,0" Name="tabControl1" VerticalAlignment="Top" Width="462">
            <TabItem Header="Person" Name="tabItem1">
                <Grid DataContext="{StaticResource peopleViewSource}">
                    <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="166" SelectedItem="{Binding personDetails}"
                              HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="64,23,0,0" Name="peopleDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="289">
                        <DataGrid.Columns>
                            <DataGridTextColumn x:Name="personIDColumn" Binding="{Binding Path=personID}" Header="person ID" Width="SizeToHeader" />
                            <DataGridTextColumn x:Name="firstNameColumn" Binding="{Binding Path=firstName}" Header="first Name" Width="SizeToHeader" />
                            <DataGridTextColumn x:Name="lastNameColumn" Binding="{Binding Path=lastName}" Header="last Name" Width="SizeToHeader" />
                        </DataGrid.Columns>
                            <DataGrid.Triggers>
                                <EventTrigger RoutedEvent="DataGrid.SelectionChanged" >
                                    <BeginStoryboard>
                                        <Storyboard >
                                            <Int32AnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="tabControl1" Storyboard.TargetProperty="SelectedIndex">
                                                <SplineInt32KeyFrame KeyTime="00:00:00" Value="1"/>
                                            </Int32AnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </DataGrid.Triggers>
                    </DataGrid>
                </Grid>
            </TabItem>
         ......
    

    Here is my mockup

    Code:

    namespace WpfApplication7
    {
        public partial class MainWindow : Window
        {
    
            private Person _selectedPerson;
            private ObservableCollection<Person> _persons = new ObservableCollection<Person>();
    
            public MainWindow()
            {
                InitializeComponent();
                Items.Add(new Person { personID = "Stack" });
                Items.Add(new Person { personID = "Overflow" });
            }
    
            public ObservableCollection<Person> Items
            {
                get { return _persons; }
                set { _persons = value; }
            }
    
            public Person SelectedPerson
            {
                get { return _selectedPerson; }
                set { _selectedPerson = value; }
            }
    
        }
    
        public class Person
        {
            public string personID { get; set; }
            public string firstname { get; set; }
            public string lastname { get; set; }
        }
    }
    

    Xaml:

    <Window x:Class="WpfApplication7.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="399" Width="464" Name="UI" >
    
        <Grid>
            <TabControl Height="270" HorizontalAlignment="Left" Margin="16,23,0,0" Name="tabControl1" VerticalAlignment="Top" Width="462">
                <TabItem Header="Person" Name="tabItem1">
                    <Grid DataContext="{Binding ElementName=UI, Path=Items}" >
                        <DataGrid  AutoGenerateColumns="False" EnableRowVirtualization="True" Height="166" SelectedItem="{Binding personDetails}"
                              HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="64,23,0,0" Name="peopleDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="289">
                            <DataGrid.Columns>
                                <DataGridTextColumn x:Name="personIDColumn" Binding="{Binding Path=personID}" Header="person ID" Width="SizeToHeader" />
                                <DataGridTextColumn x:Name="firstNameColumn" Binding="{Binding Path=firstName}" Header="first Name" Width="SizeToHeader" />
                                <DataGridTextColumn x:Name="lastNameColumn" Binding="{Binding Path=lastName}" Header="last Name" Width="SizeToHeader" />
                            </DataGrid.Columns>
                            <DataGrid.Triggers>
                                <EventTrigger RoutedEvent="DataGrid.SelectionChanged" >
                                    <BeginStoryboard>
                                        <Storyboard >
                                            <Int32AnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="tabControl1" Storyboard.TargetProperty="SelectedIndex">
                                                <SplineInt32KeyFrame KeyTime="00:00:00" Value="1"/>
                                            </Int32AnimationUsingKeyFrames>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </DataGrid.Triggers>
                        </DataGrid>
                    </Grid>
                </TabItem>
                <TabItem Header="Person Details" Name="tabItem2">
                    <Grid>
                        <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="120" SelectedItem="{Binding personDetails.personStatus}"
                              HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="82,18,0,0" Name="personDetailsDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="172">
                            <DataGrid.Columns>
                                <DataGridTextColumn x:Name="detailIDColumn" Binding="{Binding Path=detailID}" Header="detail ID" Width="SizeToHeader" />
                                <DataGridTextColumn x:Name="positionColumn" Binding="{Binding Path=position}" Header="position" Width="SizeToHeader" />
                                <DataGridTextColumn x:Name="personIDColumn1" Binding="{Binding Path=personID}" Header="person ID" Width="SizeToHeader" />
                            </DataGrid.Columns>
                        </DataGrid>
                    </Grid>
                </TabItem>
                <TabItem Header="Person Status" Name="tabItem3">
                    <Grid>
                        <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="143" HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="91,23,0,0" Name="personStatusDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="185">
                            <DataGrid.Columns>
                                <DataGridTextColumn x:Name="detailIDColumn1" Binding="{Binding Path=detailID}" Header="detail ID" Width="SizeToHeader" />
                                <DataGridTextColumn x:Name="positionColumn1" Binding="{Binding Path=position}" Header="position" Width="SizeToHeader" />
                                <DataGridTextColumn x:Name="statussColumn" Binding="{Binding Path=statuss}" Header="statuss" Width="SizeToHeader" />
                            </DataGrid.Columns>
                        </DataGrid>
                    </Grid>
                </TabItem>
            </TabControl>
        </Grid>
    </Window>