I have an application that, when clicked, loads a new tabitem using usercontrol. This works great, but ... When I click the Add button again, another tabitem is added with a new instance of usercontrol. This is where the problem arises. When I add some data to tab1 and switch to tab2, I also see the entered data there. How is this possible? I am using a new viewmodel for each usercontrol since both user controls on tab1 and tab2 show the same data. It will probably be something stupid, but I can not find it ...
The structure looks like this: MainWindow loads the UserControl using only the tabcontrol. After clicking the "Add" button, a new tabitem is added to the menu with a new user control on it.
There is SO here, some of which look like this, but different.
Here is the code.
TabControl.xaml:
<Grid> <TabControl x:Name="tabControl" ItemsSource="{Binding TabItems}" SelectedIndex="0"> <TabControl.Resources> <DataTemplate DataType="{x:Type ViewModel:OverviewViewModel}"> <my:OverviewControl /> </DataTemplate> <DataTemplate DataType="{x:Type ViewModel:MemberViewModel}"> <my:MemberControl /> </DataTemplate> </TabControl.Resources> <TabControl.ItemContainerStyle> <Style TargetType="TabItem"> <Setter Property="Header" Value="{Binding Header}" /> </Style> </TabControl.ItemContainerStyle> </TabControl> </Grid>
TabControl.cs
public TabControl() { InitializeComponent(); this.DataContext = new TabViewModel(true); }
TabViewModel has a DP that contains tabits:
public static readonly DependencyProperty TabItemsProperty = DependencyProperty.Register("TabItems", typeof(ObservableCollection<ITabViewModel>), typeof(TabViewModel), new UIPropertyMetadata(new ObservableCollection<ITabViewModel>())); public ObservableCollection<ITabViewModel> TabItems { get { return (ObservableCollection<ITabViewModel>)GetValue(TabItemsProperty); } set { SetValue(TabItemsProperty, value); } }
A user control that loads on tabitem, MemberControl.cs
public MemberControl() { InitializeComponent(); this.DataContext = new MemberViewModel{}; }
MemberControlViewModel element:
private MemberModel _memberModel = new MemberModel(); public MemberViewModel() { Address = new AddressViewModel(); } public static readonly DependencyProperty FirstNameProperty = DependencyProperty.Register("FirstName", typeof(string), typeof(MemberViewModel), new UIPropertyMetadata(string.Empty, OnFirstNameChanged)); public string FirstName { get { return (string)GetValue(FirstNameProperty); } set { SetValue(FirstNameProperty, value); } } public static void OnFirstNameChanged(DependencyObject m, DependencyPropertyChangedEventArgs e) { var d = m as MemberViewModel; if (d._memberModel != null) d._memberModel.FirstName = d.FirstName; } public static readonly DependencyProperty LastNameProperty = DependencyProperty.Register("LastName", typeof(string), typeof(MemberViewModel), new UIPropertyMetadata(string.Empty, OnLastNameChanged)); public string LastName { get { return (string)GetValue(LastNameProperty); } set { SetValue(LastNameProperty, value); } } public static void OnLastNameChanged(DependencyObject m, DependencyPropertyChangedEventArgs e) { var d = m as MemberViewModel; if (d._memberModel != null) d._memberModel.LastName = d.LastName; } etc...
And then finally, a command on my menu that actually adds the membercontrol control as a new tabitem to tabcontrol:
private void LoadNewMember(object notUsed) { _tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" }); _addOverview.RaiseCanExecuteChanged(); }
A little along the way, I am doing something wrong with the binding, but as said, I can not find it.
Thanks for any help.