Multiple instances of a wpf user control use the same view model

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.

+4
source share
1 answer

You seem to set the DataContext of each MemberControl .

Once you add MemberViewModel to your tab collection:

 _tabViewModel.TabItems.Add(new MemberViewModel { Header = "New Member" }); 

this will create a MemberControl due to the DataTemplate you set.

Then, in your MemberControl constructor MemberControl you then reset the DataContext to add a new instance of MemberViewModel :

 public MemberControl() { InitializeComponent(); this.DataContext = new MemberViewModel{}; } 

I assume that you get the default values ​​in both tabs because of this second new .

+3
source

Source: https://habr.com/ru/post/1403921/


All Articles