简体   繁体   中英

Dynamically creating regions with Prism

I am creating an app with Prism and am running into a bit of a roadblock.

I have a tab control that is a prism region and has an ItemsSource collection that we are binding a model to. This model contains the data needed to set the tab caption, a view name, and a random id (Guid in this case) that we use to generate a dynamic prism region to be a container in the tab content with its own prism regions and can be navigated to.

+Prism region(tab control)
|+ Prism region (dynamically created with Guid name)
 |+ Inserted view
  |+ Prism region
  |+ Prism region
  |+ Prism region
|+ Prism region (dynamically created with Guid name)    |
 |+ Inserted view
  |+ Prism region
  |+ Prism region
  |+ Prism region

The hiccup I am running into is the region we are trying to generate does not appear to be registered within the region manager even though we appear to be registering them correctly.

A series of searches and questions around the team have not brought any working solutions unfortunately.

I am wondering if anyone has tried this before or if there are any good resources on dynamically generating prism regions in code and registering them.

I have done this in my application. Here is the code I came up with:

string regionName = "MyRegionName";
ContentPresenter RegionContentControl = new ContentPresenter { Focusable = false };

// This creates the region
Microsoft.Practices.Prism.Regions.RegionManager.SetRegionName(RegionContentControl, regionName);

// This adds the region to your region manager.
Microsoft.Practices.Prism.Regions.RegionManager.SetRegionManager(RegionContentControl, RegionManager);

// Get the region back
IRegion newRegion = RegionManager.Regions.FirstOrDefault(x => x.Name == regionName);

I get the RegionManger from Unity.

Update:

Mark noted that a ContentPresenter is not allowed out of the box. Here is the adapter that adds that functionallity in:

public class ContentPresenterRegionAdapter : RegionAdapterBase<ContentPresenter>
{
    public ContentPresenterRegionAdapter(IRegionBehaviorFactory behaviorFactory)
        : base(behaviorFactory)
    {
    }

    protected override void Adapt(IRegion region, ContentPresenter regionTarget)
    {
        region.Views.CollectionChanged += (s, e) =>
            {
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (FrameworkElement element in e.NewItems)
                    {
                        regionTarget.Content = element;
                    }
                }
                else if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                     foreach (FrameworkElement currentElement in e.OldItems)
                         regionTarget.Content = null;
                }
            };
    }

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

To register this mapping you would need to add this to your bootstrapper:

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
   RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
   mappings.RegisterMapping(typeof(ContentPresenter), 
                            Container.Resolve<ContentPresenterRegionAdapter>());
   return mappings;
}

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