Wpf Cann't get into the SelectionChanged event for at tabControl

simsenVejle

Well-known member
Joined
Feb 14, 2021
Messages
46
Programming Experience
Beginner
Hi
I have the following TabControl with TabItems. I need to make som code when the Selection changes to another tab.

First time I run the app I am going into the SelectionChanged. But then when choosing a new tab nothing happens at all. I want to go into the code each time, I hit the tabs. What do I have to do to get that?
TabControl:
<TabControl x:Name="tabAccountView" Style="{StaticResource tabControlLarge}" SelectionChanged="tabAccountView_OnSelectionChanged">
            <TabItem Name="tabPlatform" Header="Platform" Style="{StaticResource tabItemLarge}">
                <local:AccountPlatformView x:Name="AccountPlatformView" />
            </TabItem>
            <TabItem Name="tabEnvironment" Header="Miljø" Style="{StaticResource tabItemLarge}">
                <local:AccountEnvironmentView x:Name="AccountEnvironmentView" />
            </TabItem>
            <TabItem Name="tabEnvironmentVersion" Header="Miljø Version" Style="{StaticResource tabItemLarge}">
                <local:AccountEnvironmentVersionView x:Name="AccountEnvironmentVersionView" />
            </TabItem>
            <TabItem Name="tabComponent" Header="Komponent" Style="{StaticResource tabItemLarge}">
                <local:AccountComponentView x:Name="AccountComponentView" />
            </TabItem>
            <TabItem Name="tabPriority" Header="Prioritet" Style="{StaticResource tabItemLarge}">
                <local:AccountPriorityView x:Name="AccountPriorityView" />
            </TabItem>
            <TabItem Name="tabSeverity" Header="Sværhedsgrad" Style="{StaticResource tabItemLarge}">
                <local:AccountSeverityView x:Name="AccountSeverityView" />
            </TabItem>
            <TabItem Name="tabStatus" Header="Status" Style="{StaticResource tabItemLarge}">
                <local:AccountStatusView x:Name="AccountStatusView" />
            </TabItem>
            <TabItem Name="tabCategory" Header="Kategori" Style="{StaticResource tabItemLarge}">
                <local:AccountCategoryView x:Name="AccountCategoryView" />
            </TabItem>
        </TabControl>

Codebehind code:
private void tabAccountView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //test 1
            if (e.Source is TabControl)
            {
                //test 2
                if (tabEnvironmentVersion.IsSelected)
                {
                    //test 3
                    //Hente viewModel og opdater Environments
                    EnvironmentVersionViewModel vm = new EnvironmentVersionViewModel();
                    vm.Update();
                }
            }         
        }
Best regards
SImsen :)
 
Last edited by a moderator:
Solution
You need to update your model that has the list of environments, and then notify the view model(s) that are exposing that model to your combox(es). Recall that the view talks to the view model. The view model just provides a way for the view to talk to the back end data model. If you update the model, then the view will eventually get told about the change and update. This is why dependency injection is important. You'll just want one instance of the model so that all your view models are talking to that one instance of the data model. When te model gets update, the view models know about it. Depending on what you are doing, sometimes you can also get away with having just one instance of a view model and have multiple views talk to...
It doesn't look like that view model you instantiate on line 11 is bound to any view.
 
It doesn't look like that view model you instantiate on line 11 is bound to any view.
Hi,
That isn't my focus point right now (I will when I get into the event) = I don't get into the tabAccountView_OnSelectionChanged when changing the tab. So I even not get into line 3 when clicking on a tab.

I only get into the line 3 when starting the app. I really don't know why it wont get into the event when clicking on a tab?

Best regards
Simsen :)
 
If you can make it to line 3 then make use of your debugger. Step through the code and inspect the various objects to see what condition is not being met.

If you are not even getting to line 3, then perhaps you are applying some kind of style (or an action trigger within that style) that is preventing the tab selection from happening.

I recommend starting out with a bare minimum code and then incrementally add your styles or other code until it stops working. Then you'll figure out what is causing it to break.

For me the following works and I get the event to fire:
C#:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SimpleWpf
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Trace.WriteLine($"Changed {e.Source}");
        }
    }
}

C#:
<Window x:Class="SimpleWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SimpleWpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TabControl SelectionChanged="TabControl_SelectionChanged">
            <TabItem  Header="Left"/>
            <TabItem Header="Right"/>
        </TabControl>
    </Grid>
</Window>
 
If you can make it to line 3 then make use of your debugger. Step through the code and inspect the various objects to see what condition is not being met.

If you are not even getting to line 3, then perhaps you are applying some kind of style (or an action trigger within that style) that is preventing the tab selection from happening.

I recommend starting out with a bare minimum code and then incrementally add your styles or other code until it stops working. Then you'll figure out what is causing it to break.

For me the following works and I get the event to fire:
C#:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SimpleWpf
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Trace.WriteLine($"Changed {e.Source}");
        }
    }
}

C#:
<Window x:Class="SimpleWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SimpleWpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TabControl SelectionChanged="TabControl_SelectionChanged">
            <TabItem  Header="Left"/>
            <TabItem Header="Right"/>
        </TabControl>
    </Grid>
</Window>
Hi
My problem is that I cann't make it to line 3. Only when starting the app, but not when switching tabs :)
 
If you can make it to line 3 then make use of your debugger. Step through the code and inspect the various objects to see what condition is not being met.

If you are not even getting to line 3, then perhaps you are applying some kind of style (or an action trigger within that style) that is preventing the tab selection from happening.

I recommend starting out with a bare minimum code and then incrementally add your styles or other code until it stops working. Then you'll figure out what is causing it to break.

For me the following works and I get the event to fire:
C#:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SimpleWpf
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Trace.WriteLine($"Changed {e.Source}");
        }
    }
}

C#:
<Window x:Class="SimpleWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SimpleWpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TabControl SelectionChanged="TabControl_SelectionChanged">
            <TabItem  Header="Left"/>
            <TabItem Header="Right"/>
        </TabControl>
    </Grid>
</Window>
I will try out in a clean solution and returning back, when I know where it goes wrong. Thank You :)
 
I will try out in a clean solution and returning back, when I know where it goes wrong. Thank You :)
Hi,
You were right, and I was wrong.

It's embarrassing to say it, but I'm sick, and sometimes I can 't overlook things.

When I said it did not go into the method, I had just forgotten to make a brake point.

I have done so now, and it also goes into it, but unfortunately it does not do what I want it to.

First what I do;

I go into Environment and add a new one so there are now 7 rows.

When I then go to the page with EnvironmentVersion, and want to add a new one, there is a combobox where it must retrieve all environments (ie 7), but it now only shows 6.

I thought I would do a refresh of the combo box, but it does not work, so what should I do?

I was considering if I could download EnvironnemtViewModel and then use the (public) LoadEnvironment () method, but do not know how?

TabAccountView_SelectionChanged:
private void TabAccountView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
           
            //test 1
            if (e.Source is TabControl)
            {
                //test 2
                if (tabEnvironmentVersion.IsSelected)
                {
                    //test 3
                    //Hente viewModel og opdater Environments

                    string test4 = AccountEnvironmentVersionView.CbxEnvironment.Items.Count.ToString();
                    //CbxInactiveEnvironment
                    string cbxEnvironmentCount1 =  AccountEnvironmentVersionView.CbxEnvironment.Items.Count.ToString();

                    //Here I try to refresh the combobox but nothing happens.
                    AccountEnvironmentVersionView.CbxEnvironment.Items.Refresh();
                    string cbxEnvironmentCount2 = AccountEnvironmentVersionView.CbxEnvironment.Items.Count.ToString();

                    AccountEnvironmentVersionView.CbxEnvironment.Items.Refresh();
                    string test5 = AccountEnvironmentVersionView.CbxEnvironment.Items.Count.ToString();
                    EnvironmentVersionViewModel vm = new EnvironmentVersionViewModel();
                    vm.Update();
                }
            }          
        }

Where my coboBox is:
C#:
<ComboBox x:Name="CbxEnvironment" Grid.Row="4" Grid.Column="2" HorizontalContentAlignment="Left"  VerticalContentAlignment="Center"
                                      ItemsSource="{Binding Path=Environment_GetActive}" DisplayMemberPath="EnvironmentName"
                                      SelectedValuePath="EnvironmentId"
                                      Text="{Binding ElementName=LivEnvironmentVersions, Path=SelectedValue.EnvironmentName, Mode=TwoWay}"
                                      SelectedValue="{Binding ElementName=LivEnvironmentVersions, Path=SelectedValue.EnvironmentId, Mode=TwoWay}"
                                       Style="{StaticResource ComboBox}">
                            </ComboBox>

And the LoadEnvironment in my EnvironmentViewModel:

LoadEnvironment:
public void LoadEnvironment()

        {

            DalEnvironment dalEnvironment = new DalEnvironment();

            var Environments = dalEnvironment.GetEnvironments();



            if (Environments != null)

            {

                //All

                List<Environment> Environments_GetAllList = Environments;

                Environments_GetAll = new ObservableCollection<Environment>(Environments_GetAllList);



                //Active

                List<Environment> Environments_GetActiveList = Environments.Where(x => x.EnvironmentIsObsolete == false).ToList();

                Environments_GetActive = new ObservableCollection<Environment>(Environments_GetActiveList);



                //Inactive

                List<Environment> Environments_GetInactiveList = Environments.Where(x => x.EnvironmentIsObsolete == true).ToList();

                Environments_GetInactive = new ObservableCollection<Environment>(Environments_GetInactiveList);

            }

        }

If you need any other code just say so. Nothing is secret, just me trying to leaning programming again.

Best regards
Simsen :)
 
You need to update your model that has the list of environments, and then notify the view model(s) that are exposing that model to your combox(es). Recall that the view talks to the view model. The view model just provides a way for the view to talk to the back end data model. If you update the model, then the view will eventually get told about the change and update. This is why dependency injection is important. You'll just want one instance of the model so that all your view models are talking to that one instance of the data model. When te model gets update, the view models know about it. Depending on what you are doing, sometimes you can also get away with having just one instance of a view model and have multiple views talk to that one instance. When the view model gets updated, then all the views talking to that instance also get updated since you should have been binding to the view model.
 
Last edited:
Solution
Back
Top Bottom