The following situation occurred ... There is a TabControl on the form and 2 buttons. The first button adds new tabs to TabControl and the already prepared UserControl is placed in the "Content" of these tabs (it has its objects / properties and methods).

The second button, on ideas, should address any of the methods of this UserControl itself.

Actually the question consists in the following: how to access objects / properties / methods of dynamically created UserControl in different tabs. For example: 2 tabs were created and by clicking on the second button, access to the UserControl occurs only to the one whose tab is now in focus.

Nefiga in words is not clear, so I will draw a layout in Peinte. enter image description here

There are no problems with creating tabs and placing UserControl in them, they do it like this:

The code for the button that adds the tab:

mainTab.Items.Insert(mainTab.Items.Count - 1, AddTabItem("test_" + mainTab.Items.Count)); 

 private TabItem AddTabItem(string nametab) { UserControl1 uc = new UserControl1(); TabItem tab = new TabItem(); tab.Header = nametab; tab.Content = uc; return tab; } 

I do not use any "ItemSource", "Binding". In the xml markup, the most common is TabControl, which has only the parameter "Name" and "Margin".

  • Никаких "ItemSource", "Binding" Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ. - and in vain, oh, how in vain .. - EvgeniyZ
  • Maybe. The first time I did it through ItemSource, but in such cases, if you carry out any actions in one tab (add text or something else), then it happens in all tabs at once. - keinHerz 3:04 pm
  • Do you have Control one or more in TabControl? - EvgeniyZ
  • UserControl is one, but there are many controls in UserControl itself. - keinHerz pm

2 answers 2

There must be something

 TabItem tabItem = _tabControl.Items .OfType<TabItem>() .FirstOrDefault(t => t.IsFocused == true); var uc = tabItem?.Content as UserControl1; uc?.MyMethod(); 

you will correct the condition for the search you need ...

  • Yes, sort of what you need. Thank you. - keinHerz pm
  • Yes please. - Bulson

I still think that UserControl is a View that contains a part of the view, it should have minimal logic.

Let's try to implement something like that. I personally will do with the possibility of expansion and for this I use the interface. Its role is simple, to contain the tab header:

 public interface ITabViewModel { string Header { get; set; } } 

Next we need some kind of ViewModel, which will contain the implementation of a specific tab. In my example, it will contain the title, color, text, and color update method:

 public class ViewModelA: VM, ITabViewModel { public string Header { get; set; } public string Text { get; set; } private Brush _color; public Brush Color { get => _color; set { _color = value; OnPropertyChanged(); } } public void UpdateColor(Brush color) => Color = color; } 

As you can see, we inherit from VM (this is the base class that contains INotifyPropertyChanged), and also implement the interface we created earlier.

Having all this, we can combine all this in, let's create a MainViewModel:

 public class MainViewModel { public ObservableCollection<ITabViewModel> TabItems { get; set; } = new ObservableCollection<ITabViewModel>(); public ITabViewModel SelectedTab { get; set; } public MainViewModel() { AddTestData(); //Π“Ρ€ΡƒΠ·ΠΈΠΌ Π½Π΅ΠΊΠΈΠ΅ тСстовыС Π΄Π°Π½Π½Ρ‹Π΅ TestOtherMethod(); //Π’Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρƒ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ } private void AddTestData() { //НСкиС Π΄Π°Π½Π½Ρ‹Π΅ TabItems.Add(new ViewModelA { Header = "Π’ΠΊΠ»Π°Π΄ΠΊΠ° 1", Text = "ΠŸΡ€ΠΈΠ²Π΅Ρ‚ ΠΌΠΈΡ€!", Color = Brushes.Aqua }); TabItems.Add(new ViewModelA { Header = "Π’ΠΊΠ»Π°Π΄ΠΊΠ° 2", Text = "ΠŸΡ€ΠΈΠ²Π΅Ρ‚ зСмля!", Color = Brushes.Azure }); TabItems.Add(new ViewModelA { Header = "Π’ΠΊΠ»Π°Π΄ΠΊΠ° 3", Text = "ΠŸΡ€ΠΈΠ²Π΅Ρ‚ космос!", Color = Brushes.Bisque }); //ВыдСляСм ΠΏΠ΅Ρ€Π²ΡƒΡŽ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ SelectedTab = TabItems.FirstOrDefault(); } private void TestOtherMethod() { var item = SelectedTab as ViewModelA; item?.UpdateColor(Brushes.Green); } } 

We tie the whole thing:

 private MainViewModel MainViewModel { get; } = new MainViewModel(); public MainWindow() { InitializeComponent(); DataContext = MainViewModel; } 

Now let's deal with XAML. In it, we need to create a TabControl, which will be bound via the ItemSource to our TabItems collection. We will also set the DataTemplate to the resources, so that under the defined ViewModel we get the required Control. Well, also tie the Header through the ItemContainerStyle. In the end, something like this will come out:

 <TabControl ItemsSource="{Binding TabItems}" SelectedItem="{Binding SelectedTab}"> <TabControl.Resources> <DataTemplate DataType="{x:Type local:ViewModelA}"> <local:UserControl1 Text="{Binding Text}" Color="{Binding Color}" /> </DataTemplate> </TabControl.Resources> <TabControl.ItemContainerStyle> <Style TargetType="TabItem"> <Setter Property="Header" Value="{Binding Header}" /> </Style> </TabControl.ItemContainerStyle> </TabControl> 

I will not show the Control itself; two DependencyProperty (Text and Color) are set there, the design itself consists of Border, inside of which there is a TextBlock.

Well, let's start and see what happens?

Result

As you can see, we have 3 tabs, the first one we changed to green through the code.
With this approach, you get a convenient management of all tabs, as well as the possibility of their expansion by adding another Control'a and ViewModel.

Good luck in programming!

  • Also an option, but the answer given above turned out to be more appropriate. - keinHerz 6:51 pm