简体   繁体   中英

RegisterViewWithRegion throws System.NullReferenceException for a View

I created a Prism WPF application and I tried to split it into modules. This is my MainWindow:

<Window x:Class="MyProject.WPF.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525"
        WindowState="Maximized">
    <Grid>
        <TabControl prism:RegionManager.RegionName="TabRegion"
                    VerticalAlignment="Stretch"
                    HorizontalAlignment="Stretch"
                    BorderThickness="0"/>
    </Grid>
</Window>

My InfoView:

<UserControl x:Class="Info.Views.InfoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Info.Views"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True" >
    <Grid>
        <TextBlock Text="{Binding Message}"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center" />
    </Grid>
</UserControl>

My App class:

public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.Register<MainWindowViewModel>();
            containerRegistry.Register<InfoViewModel>();
        }

        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            moduleCatalog.AddModule<MainModule>();
            moduleCatalog.AddModule<InfoModule>();
        }

        protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
        {
            base.ConfigureRegionAdapterMappings(regionAdapterMappings);
            regionAdapterMappings.RegisterMapping(typeof(TabControl), Container.Resolve<TabControlAdapter>());
        }
    }

My TabControlAdapter which I copy pasted from somewhere in the past. It worked in a previous project:

class TabControlAdapter : RegionAdapterBase<TabControl>
    {
        public TabControlAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory)
        {
        }

        protected override void Adapt(IRegion region, TabControl regionTarget)
        {
            region.Views.CollectionChanged += (s, e) =>
            {
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    foreach (UserControl item in e.NewItems)
                    {
                        regionTarget.Items.Add(new TabItem { Header = item.Name, Content = item });
                    }
                }
                else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                {
                    foreach (UserControl item in e.OldItems)
                    {
                        var tabToDelete = regionTarget.Items.OfType<TabItem>().FirstOrDefault(n => n.Content == item);
                        regionTarget.Items.Remove(tabToDelete);
                    }
                }
            };
        }

        protected override IRegion CreateRegion()
        {
            return new SingleActiveRegion();
        }
    }

And my MainModule:

public class MainModule : IModule
    {
        public void RegisterTypes(IContainerRegistry containerRegistry) {}

        public void OnInitialized(IContainerProvider containerProvider)
        {
            var regionManager = containerProvider.Resolve<IRegionManager>();
            regionManager.RegisterViewWithRegion("TabRegion", nameof(InfoView));
        }
    }

When I run the App it throws a System.NullReferenceException at line regionManager.RegisterViewWithRegion("TabRegion", nameof(InfoView)); , which I think means that the InfoView is never initialized. What am I missing or doing wrong?

Okay it was pretty obvious. I just had to register the InfoView in the MainModule:

public void RegisterTypes(IContainerRegistry containerRegistry)
{
  containerRegistry.Register<InfoView>();
}

I won't delete the question, though, because I think it gives a basic example on how to work with Prism, TabRegions and Modules.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM