Search code examples
wpfxamlprismtabcontrolregion

TabControl region, How to pass parameter to child region? WPF - Prism


I'm using prism regions in order to create dynamic TabControl. But I'm having a problem passing the object from TabItem (parent view) to its child regions. The below is the code I'm using to build the TabControl.

Shell:

xaml

<ContentControl regions:RegionManager.RegionName="ShellProjectRegion" />

ShellViewModel

regionManager.RegisterViewWithRegion(ShellProjectRegion, typeof(ProjectTabView));

ProjectTabView:

xaml

<TabControl regions:RegionManager.RegionName="ProjectTabRegion">

ProjectTabViewModel

container.RegisterType<object, ProjectView>(typeof(ProjectView).FullName);

ProjectView:

xaml

<Grid>
    <ContentControl regions:RegionManager.RegionName="ProjectExplorerRegion"
                    regions:RegionManager.RegionContext="{Binding}" />
</Grid>

ProjectViewModel

public class ProjectViewModel : BindableBase, INavigationAware, IActiveAware {
    private ProjectItem _project;
    public ProjectItem Project {
        get { return _project; }
        set { SetProperty(ref _project, value); }
    }
    public ProjectViewModel(IRegionManager regionManager) {
        regionManager.RegisterViewWithRegion("ProjectExplorerRegion", typeof(ProjectExplorerView));
    }
    public void OnNavigatedTo(NavigationContext navigationContext) {
        Project = (ProjectItem)navigationContext.Parameters["project"];
    }
}

ProjectExplorerView:

xaml.cs

public ProjectExplorerView(IUnityContainer container) {
    InitializeComponent();
    var vm = container.Resolve<ProjectExplorerViewModel>();
    RegionContext.GetObservableContext(this).PropertyChanged += (s, e) => {
        var context = (ObservableObject<object>)s;
        var projectVm = (ProjectViewModel)context.Value;
        vm.ParentProjectInfo = projectVm.Project.ProjectInfo;
    };
    DataContext = vm;
}

Note: Please note that in the last piece of code inside the ProjectExplorerView.xaml.cs the view constructor gets called multiple times each time new Tab is created. when tracing the code, the context variable gets null sometimes, and sometimes has the right value, which is the project I want to pass. but the it's always null at the end of calling the constructor.


Solution

  • So I'm not sure if this is the right way to do it, but it works. First I've removed regionManager.RegisterViewWithRegion("ProjectExplorerRegion", typeof(ProjectExplorerView)); from ProjectViewModel to ShellViewModel, this was causing the view to be called multiple times as I have mentioned at the end of my question.

    Second update the ParentProjectInfo implementation to use INotifyPropertyChanged, and inside the property setter, update what needs to be automatically updated.