1

Trying to create a TabControl Region inside another Region. The TabControl has a set number of Views that will be added to it, with their own respective ViewModels.

But either the View doesn't show up, the tabitem doesn't show up with only one View displayed instead, or I get the following error:

System.ArgumentException: 'This RegionManager does not contain a Region with the name 'ParentTabRegion'. (Parameter 'regionName')'

MainMenuView:

<Grid>
    <ContentControl prism:RegionManager.RegionName="ContentRegion" />
</Grid>

MainMenuViewModel:

public class MainMenuViewModel : BindableBase
{
    private readonly IRegionManager _regionManger;

    public MainMenuViewModel(IRegionManager regionManager)
    {
        _regionManger = regionManager;

        _regionManger.RequestNavigate("ContentRegion", "ParentView");

    }
}

ParentView:

<Grid>
    <TabControl prism:RegionManager.RegionName="ParentTabRegion" />
</Grid>

ParentViewModel:

public class ParentViewModel : BindableBase
{
    private readonly IRegionManager _regionManger;

    private Child1View _tab1 = new Child1View();
    private Child1View Tab1
    {
        get { return _tab1; }
        set { SetProperty(ref _tab1, value); }
    }
    private Child2View _tab2 = new Child2View();
    private Child2View Tab2
    {
        get { return _tab2; }
        set { SetProperty(ref _tab2, value); }
    }

    public ParentViewModel(IRegionManager regionManger)
    {
        _regionManger = regionManger;

        // Gives 'This RegionManager does not contain a Region with the name 'GeneralDataTabRegion'. (Parameter 'regionName')' error
        _regionManger.AddToRegion("ParentTabRegion", typeof(Child1View));
        _regionManger.AddToRegion("ParentTabRegion", typeof(Child2View));

        //I've also tried the following
        
        // Same error as above
        // _regionManger.Regions["ParentTabRegion"].Add(typeof(Tab1View));
        // _regionManger.Regions["ParentTabRegion"].Add(typeof(Tab2View));

        // Same error as above
        // _regionManger.AddToRegion("ParentTabRegion", Tab1);
        // _regionManger.AddToRegion("ParentTabRegion", Tab2);

        // Only the last registered view is displayed
        // _regionManger.RegisterViewWithRegion("ParentTabRegion", typeof(Tab1));
        // _regionManger.RegisterViewWithRegion("ParentTabRegion", typeof(Tab2));
    }
}

I also have the prism namespace in all the views:

xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"

Maybe I'm not registering the ParentTabRegion somehow? But I don't have to register the other regions and they seem to just work out of the box.

Let me know if you know what I'm doing wrong or if there is something I'm missing. Thank you.

Corey
  • 835
  • 1
  • 9
  • 32

3 Answers3

1

I would just comment but can't due to low reputation. Anyway..

Check this post Prism 7 throws and exception when working with nested views

As stated in the comments: "the problem is about how to inject scope region in ViewModel" This video from Brian should help you with the issue.

https://app.pluralsight.com/library/courses/prism-mastering-tabcontrol

  • Thanks, I'll check out your answer on the other question. I've viewed the "Prism Mastering TabControl", but found that it really only covered the situation where all the child views were the same amongst all the tabs. I also find it hard to follow along with some of his video's(except the one that came out this year) since they use older versions of prism. – Corey Sep 17 '20 at 12:15
1

I tested some other things out. Since I don't need dynamic tabs, I found this to be the cleanest solution using Prism:

Parent ViewModel:

public ParentViewModel(IRegionManager regionManager)
{
    _regionManager = regionManager;
    _regionManager.RegisterViewWithRegion("ChildRegion", typeof(Child1View));
    _regionManager.RegisterViewWithRegion("ChildRegion", typeof(Child2View));
}

Parent View:

<UserControl.Resources>
  <Style TargetType="TabItem">
    <Setter Property="Header"
    Value="{Binding DataContext.Title}"/>
  </Style>
</UserControl.Resources>

<Grid>
    <TabControl prism:RegionManager.RegionName="ChildRegion" />
</Grid>
Corey
  • 835
  • 1
  • 9
  • 32
0

I ended up doing this a bit differently since I don't really need to dynamically add Tabs.

So what I ended up doing was just adding all the ViewModels to an ObservableCollection of BindableBase. Then I just added them to the view using a DataTemplate.

Parent ViewModel:

private ObservableCollection <BindableBase> _childTabs;

public ObservableCollection <BindableBase> ChildTabs
{
   get { return _childTabs; }
   set { _childTabs = value; }
}

public ParentViewModel() 
{    
    ChildTabs = new ObservableCollection <BindableBase> {
      new Child1ViewModel(),
      new Child2ViewModel()
    };
}

Parent View:

<TabControl ItemsSource="{Binding ChildTabs}"
                SelectedIndex="0">
  <TabControl.Resources>
    <DataTemplate DataType="{x:Type vm:Child1ViewModel}">
      <view:Child1 />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:Child2ViewModel}">
      <view:Child2 />
    </DataTemplate>
    </DataTemplate>
  </TabControl.Resources>
  <TabControl.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Title}" />
    </DataTemplate>
  </TabControl.ItemTemplate>
</TabControl>

I still feel like I'm doing something wrong though, this doesn't feel like MVVM to me...

Corey
  • 835
  • 1
  • 9
  • 32