I'm trying to find a way to add content to a tab page using the TabControl without creating new tabs. I have a ViewModel that holds the values for the tab header and tab content. Currently, when the 'Add Tab' button is clicked, it will add a new tab with the correct heading, however the tab content will have the data missing. I understand why my work doesn't work, which is why I would like to find out if it is possible to separate these two processes. I am new to WPF and would appreciate any help.
XAML:
<TabControl ItemsSource="{Binding}" Grid.Column="1" Grid.Row="1" Grid.RowSpan="5">
<TabControl.ItemTemplate>
<DataTemplate DataType="local:MyTab">
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="local:MyTab">
<StackPanel>
<TextBlock Text="First Name:" />
<TextBlock Binding="{Binding FirstName}" Margin="0,0,0,10"/>
<TextBlock Text="Second Name:" />
<TextBlock Binding="{Binding SecondName}" Margin="0,0,0,10"/>
<TextBlock Text="ID Number:" />
<TextBlock Binding="{Binding Id}" Margin="0,0,0,10"/>
<TextBlock Text="Age:" />
<TextBlock Binding="{Binding Age}" Margin="0,0,0,10"/>
<TextBlock Text="Gender:" />
<TextBlock Binding="{Binding Gender}" Margin="0,0,0,10"/>
<TextBlock Text="Address:" />
<TextBlock Binding="{Binding Address}" Margin="0,0,0,10"/>
</StackPanel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
C#:
public partial class MainWindow : Window
{
ObservableCollection<MyTab> tabs = new ObservableCollection<MyTab>();
string firstName;
string secondName;
string id;
int age;
string gender;
string address;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
firstName = firstNameTxtBox.Text;
secondName = surnameTxtBox.Text;
var tab = new MyTab() { Header = firstName + " " + secondName };
tabs.Add(tab);
DataContext = tabs;
firstNameTxtBox.Clear();
surnameTxtBox.Clear();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
id = idTxtBox.Text;
age = Convert.ToInt32(ageTxtBox.Text);
gender = genderTxtBox.Text;
address = addressTxtBox.Text;
var tab = new MyTab();
tab.Data.Add(new MyTabData() { FirstName = firstName, SecondName = secondName, Id = id, Age = age, Gender = gender, Address = address });
tabs.Add(tab);
DataContext = tabs;
idTxtBox.Clear();
ageTxtBox.Clear();
genderTxtBox.Clear();
addressTxtBox.Clear();
}
}
As I understood,
MyTabis your class, that will look like that :First of all, your class must be
INotifyPropertyChangedso the binding of TextBoxes will work.Then your MainWindows : Window, INotifyPropertyChanged
You must set the dataContext (if you ant to do it properly (MVVM), you may set the context in a different file named
ViewModelMainWindows.csfor example.The
ViewModelpart :Then xaml look like that :
TabControl's content is linked to ListMyTab (one TabItem for each object MyTab). Then the content of each TabItem is binded to each item. So when you will edit FirstName in the TextBlock (I would use TextBox instead), the header will be automaticaly updated (this is Binding power).
If you want to add a new item, then add somewhere a button, with that :
It will add an item in observable collection, then a new tab will appear.
Also for your tab appearance, I'd advise you to have a look at that :