0

Im trying to get the previous selected tabs content when it is changed to another in a TabControl. For this i subscribe to the SelectionChanged event like so:

tabControl.SelectionChanged += getPreviousData

Then the getPreviousData method looks like this:

private void getPreviousData(object sender, SelectionChangedEventArgs e)
{
    e.RemovedItems[0].something
}

Im a little unsure as to how i grab the previous tab content. The previous tab has a textbox control that i need to get the name of, when i change the tab. How can i accomplish that?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Daniel Jørgensen
  • 1,183
  • 2
  • 19
  • 42

2 Answers2

4

Assuming you have a XAML like that

<TabControl x:Name="tabControl" SelectionChanged="tabControl_SelectionChanged">
    <TabItem Header="TabItem">
        <Grid Background="#FFE5E5E5">
            <TextBox Width="100" Height="23"></TextBox>
        </Grid>
    </TabItem>
    <TabItem Header="TabItem">
        <Grid Background="#FFE5E5E5">
            <TextBlock x:Name="TextBlock"></TextBlock>
        </Grid>
    </TabItem>
</TabControl>

First option

Then you can access children of removed TabItem using this code

private void tabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    if (e.RemovedItems.Count != 0)
    {
        var tabItem = (TabItem)e.RemovedItems[0];
        var content = (Grid)tabItem.Content;
        var textBox = content.Children.OfType<TextBox>().First();
        var text = textBox.Text;
    }
}

Second option

You can name your textbox

<TextBox x:Name="TextBoxInFirstTab" Width="100" Height="23"></TextBox>

And access it using his name

var text2 = TextBoxInFirstTab.Text;

Third option

Use MVVM, check this answer MVVM: Tutorial from start to finish?

I am going to provide a simple sample, without any framework, but I suggest you to use anyone, like MVVM Light ToolKit.

  1. Create a View Model
  2. Implement the INotifyPropertyChanged interface
  3. Create a property that will hold your text value, and in the set call the OnPropertyChanged
public class MyViewModel : INotifyPropertyChanged
{
    private string _textInFirstTab;

    public string TextInFirstTab
    {
        get { return _textInFirstTab; }
        set
        {
            _textInFirstTab = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Then in your Window constructor, set the DataContext property from Window, to a new instance for your MyViewModel.

public MainWindow()
{
    InitializeComponent();
    this.DataContext = new MyViewModel();
}

Then in your XAML set the Text attribute with a Binding expression

<TextBox x:Name="TextBox" Width="100" Height="23" Text="{Binding TextInFirstTab}"></TextBox>

And in your tabControl_SelectionChanged event, you can access the value like that:

private void tabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    if (e.RemovedItems.Count != 0)
    {
        var myViewModel = (MyViewModel)DataContext;
        var text = myViewModel.TextInFirstTab;
    }
}
Community
  • 1
  • 1
Alberto Monteiro
  • 5,989
  • 2
  • 28
  • 40
0

If it is switching between existing tabs which you are after, then I would suggest simply storing the index of the selected tab in a class variable.

Sample code looks like this:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // variable to store index of tab which was most recently selected
        private int lastSelectedTabIndex = -1;

        public Form1()
        {
            InitializeComponent();

            // initialise the last selected index
            lastSelectedTabIndex = tabControl1.SelectedIndex;
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // sanity check: if something went wrong, don't try and display non-existent tab data
            if (lastSelectedTabIndex > -1)
            {
                MessageBox.Show(string.Format("Previous tab: {0} - {1}", lastSelectedTabIndex, tabControl1.TabPages[lastSelectedTabIndex].Text));
            }

            // store this tab as the one which was most recently selected
            lastSelectedTabIndex = tabControl1.SelectedIndex;
        }
    }
}

This was written and tested in a simple application with one form and a TabControl added. No changes were made to the default properties.

You will, of course, have to hook into the event handler. I did so by double-clicking it in the IDE, but you could also hook in manually by adding:

        this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);

to the form constructor, called "Form1()" in the example code.

Getting the name of a textbox is an unusual thing to want to do. May I ask what you are trying to achieve? There's probably a better way to do it than trying to determine the name of a control.

Hamish
  • 119
  • 7