I Get an Exception when accessing Regions information

Aug 8, 2012 at 2:48 PM
Edited Aug 8, 2012 at 2:51 PM

I'm using SL 5 and Prism v4.1.

I have two Modules in two regions.

CustomersModule (LeftRegion) shows Customers and OrdersModule (RightRegion) shows the orders of the selected customer in the left region.

I have a EventAggregator that handles the communication between these two modules. This EventAggregator uses the SelectedCustomer method.

In the SelectedCustomer method I try to get a handle to the RightRegion in order to inject the OrdersView but I get this exception that says "Region with the given name is already registered: RightRegion".

As you can see, I'm not trying to register the region, just getting a handle to the region for a latter use.

The complete CustomerSelected methos is:

private void CustomerSelected(Customer currCustomer) {
    if (currCustomer == null)
        return;

    IRegion rightRegion = this.regionManager.Regions["RightRegion"];
    if (rightRegion == null)
        return;

    CustomersSummaryView view = rightRegion.GetView("CustomersSummaryView") as CustomersSummaryView;
    if (view == null) {
        // Create a new instance of the EmployeeDetailsView using the Unity container.
        view = this.container.Resolve<CustomersSummaryView>();

        // Add the view to the main region. This automatically activates the view too.
        rightRegion.Add(view, "CustomersSummaryView");
    }
    else {
        // The view has already been added to the region so just activate it.
        rightRegion.Activate(view);
    }

    CustomersSummaryViewModel viewModel = view.DataContext as CustomersSummaryViewModel;
    if (viewModel != null) {
        viewModel.CurrentCustomer = currCustomer;
    }
}

I'm placing this CustomerSelected method inside the OrdersModule class, here's that class:

public class OrdersModule : IModule {
    private readonly IEventAggregator eventAggregator;
    private readonly IUnityContainer container;
    private readonly IRegionManager regionManager;

    public OrdersModule(IUnityContainer container, IRegionManager regionManager, IEventAggregator eventAggregator) {
        this.container = container;
        this.regionManager = regionManager;
        this.eventAggregator = eventAggregator;
    }

    public void Initialize() {
        this.eventAggregator.GetEvent<CustomerSelectedEvent>().Subscribe(CustomerSelected, true);

        this.regionManager.RegisterViewWithRegion("RightRegion",
                                                    () =>
                                        this.container.Resolve<OrdersView>());
    }

    private void CustomerSelected(Customer currCustomer) {
        if (currCustomer == null)
            return;

    ...
    }
}
(Note that I'm subscribing to the event in the Initialize method)

Here is the Shell that defines the regions:

<Grid x:Name="LayoutRoot"
        Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="700" />
        <ColumnDefinition Width="3*" />
    </Grid.ColumnDefinitions>
    <TextBlock Text="My Prism Solution"
                FontSize="36"
                TextAlignment="Left"
                HorizontalAlignment="Center"
                Grid.ColumnSpan="2" />
    <Border Grid.Row="1">
        <ContentControl x:Name="LeftRegion"
                        prism:RegionManager.RegionName="LeftRegion"
                        VerticalContentAlignment="Stretch"
                        HorizontalContentAlignment="Stretch" />
    </Border>

    <Border Grid.Column="1"
            Grid.Row="1"
            Grid.RowSpan="2">
        <ContentControl x:Name="MainRegion"
                        prism:RegionManager.RegionName="RightRegion"
                        VerticalContentAlignment="Stretch"
                        HorizontalContentAlignment="Stretch">
        </ContentControl>
    </Border>
</Grid>

The method that publishes the event is Customers_CurrentChanged located in CustomersViewModel in CustomersModule.

void Customers_CurrentChanged(object sender, EventArgs e) {
    Customer currCustomer = this.Customers.CurrentItem as Customer;
    if (currCustomer != null) {
        this.eventAggregator.GetEvent<CustomerSelectedEvent>().Publish(currCustomer);
    }
}

The whole structure of the solution is:

Hope you can detect the problem with this information, but if you need more, just tell me what...

My best regards

Rafael

Developer
Aug 8, 2012 at 6:19 PM

Hi Rafael,

So far we were unable to find the reason behind this problem within the code snippets you provided.

There have been reports of similar problems in the past which were mainly related to how the region behaviors and the region manager works. However, this is the first time we see this error with a region declared in the shell.

It would be helpful if you could provide us with a repro-sample application, so that we can check it in further detail and help you find the cause behind this problem. You can upload your repro-sample application, for example, in SkyDrive or in any other file hosting service of your preference and post the link here.

Thanks,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Aug 9, 2012 at 8:48 PM
Edited Aug 9, 2012 at 8:48 PM

Hi Damian:

I already loaded my project (along with a backup of the database) into SkyDrive, but I don't know how to allow you to open it.

Could you please tell me how to do it?., I'm trying to receive answer from a Windows forum, but I don't get it.

Developer
Aug 10, 2012 at 12:51 PM

Hi Rafael,

Once you uploaded the project to your SkyDrive account, you could copy the URL from your browser when navigating your files inside the account, and then paste the URL in the thread as a text or as a link, so you can share your files with other people.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Aug 10, 2012 at 1:23 PM
Edited Aug 10, 2012 at 2:43 PM

Hi Agustin:

The URL I see once in my accountin in front of the rar file is: https://skydrive.live.com/#cid=228822BB183339A9&id=228822BB183339A9%21234

When I try this address SkyDrive asks for the Windows Live ID, I don't know how to suppress this behavior.

There's a "Share" option for each file in the drive, but it asks for an email address.

My best regards,

Rafael

Developer
Aug 10, 2012 at 2:54 PM

Hi,

In order to allow other people to see your file you will have to change the permissions of the folder containing the file. Based on my understanding, this can be achieved in the details pane on the right, (if it is collapsed, expand it), then for example in the Get a link option, you could choose the Public option.

Also, you could find more information about how to set this configuration in the following article:

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Aug 10, 2012 at 8:13 PM

Ok Agustin.

It's public, now you can use it.

Thank you for your patience.

My best regards,

Rafael

Aug 13, 2012 at 5:40 AM
Edited Aug 13, 2012 at 2:26 PM

Hi Agustin:

I made some tests with UICompositionQuickStart.

I ran it and it went well, then I just deleted the Prism references in the solution explorer and re-added them again, when I ran it, I got an exception.

 

Developer
Aug 13, 2012 at 8:12 PM

Hi Rafael,

After checking your application we found that the reason behind this problem is that you are actually defining a "RightRegion" in two different places, one in the Shell and one in the CustomersSummaryView. As a RegionManager cannot have two regions with the same name, the exception is thrown.

This problem can be solved changing the name of the inner region to be different from the name of the Shell's RightRegion or adding the CustomersSummaryView with a scoped region manager, doing something like this:

rightRegion.Add(view, "CustomersSummaryView", true);

You can find more information about this in the following chapter of the Prism documentation:

Usually, when adding a view that contains a region with an existing name, this exception is thrown in the Add method of the region. However, it seems that due to how the view is added, the RegionManager didn't know the "inner region" until you requested for a "RightRegion" again. Due the this and that we didn't know that the CustomersSummaryView also had a RightRegion, we initially supposed that this was related to other issue.

I hope this helps,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Aug 13, 2012 at 10:57 PM

Thanks a lot Damian!!!