ItemsControl seems to be only region type that works.

Jul 26, 2008 at 7:28 PM
Here is my shell.xaml file:  

I have tried to load.  I am loading UserControls in every region.  Wheneever i try to replace the ItemsControl with anything else ( other than TabControl ) , nothing appears in the region.  Does anybody have some samples of getting ContentControl to work as the region?

<

 

Window x:Class="PortfolioTracker.Shell"

 

 

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

 

 

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 

 

xmlns:cal="http://www.codeplex.com/CompositeWPF"

 

 

Name="Window"

 

 

Title="Shell" Height="500" Width="Auto">

 

 

 

<Grid>

 

 

 

<Grid.ColumnDefinitions>

 

 

 

<ColumnDefinition />

 

 

 

<ColumnDefinition />

 

 

 

 

</Grid.ColumnDefinitions>

 

 

 

<DockPanel x:Name="LeftDoc" Background="#feca00" Grid.Column="0" LastChildFill="True">

 

 

 

<ItemsControl Background="Gray" Width="{Binding ElementName=LeftDoc, Path=Width}" Height="{Binding ElementName=LeftDoc, Path=Height}" cal:RegionManager.RegionName="LeftRegion"/>

 

 

 

</DockPanel>

 

 

 

<GridSplitter Background="Gray" Width="5"

 

 

/>

 

 

 

 

<DockPanel x:Name="Doc" Grid.Column="1" Grid.ColumnSpan="1">

 

 

 

<ItemsControl DockPanel.Dock="Bottom" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" cal:RegionManager.RegionName="MainRegion" >

 

 

 

<ItemsControl.ItemsPanel>

 

 

 

<ItemsPanelTemplate>

 

 

 

<DockPanel LastChildFill="True"/>

 

 

 

</ItemsPanelTemplate>

 

 

 

</ItemsControl.ItemsPanel>

 

 

 

</ItemsControl>

 

 

 

</DockPanel>

 

 

 

</Grid>

 

 

 

 

 

</

 

Window>

 

Jul 26, 2008 at 10:00 PM

Hi, if you are using a ContentControl as region, you have to call the method Activate of the region after adding the view in order to show the view.
The ItemsControlRegionAdapter and the ContentControlRegionAdapter uses different regions (one use the AllActiveRegion region and the other one use the SingleActiveRegion region), that's why the behavior is different.

Please let me know if this helps,

Ezequiel Jadib
http://blogs.southworks.net/ejadib

Aug 19, 2008 at 1:54 AM

Z,

I saw the same behavior described above. Is this a bug? I noticed it before I left the office, so I did not get a chance to look into it. Calling the Active after you add it seems unnatural and unnecessary. Will this be fixed?

Thanks for the response, in advance.

Andres Olivares.

Aug 19, 2008 at 5:10 AM
Edited Aug 20, 2008 at 1:24 AM
The following update to the Add() method in region.cs will let the baseclass do the work for you :)  

Composite.Wpf | Regions | Region.cs

public virtual IRegionManager Add(object view, string viewName, bool createRegionManagerScope)
{
    IRegionManager regionManager = createRegionManagerScope
            ?
this.RegionManager.CreateRegionManager() : this.RegionManager;

    InnerAdd(view, viewName, regionManager);

    // BillKrat.2008.08.18 - activate view after adding it so 
    // that the region.ActiveViews.CollectionChanged event will
    // fire in ContentControlRegionAdapter (updates content)

    if
(this is SingleActiveRegion)
        Activate(view);

 

 

    return regionManager;
}

 

 

Aug 30, 2008 at 1:53 AM
Edited Aug 30, 2008 at 1:56 AM

BillKrat,

I resolved the same problem differently in case there was a future use case unattended.

I overrode InnerAdd in Region to look like the following:

private void InnerAdd(object view, string name, IRegionManager regionManager, bool activate)
{
 if (ItemMetadataCollection.FirstOrDefault(x => x.Item == view) != null)
  throw new InvalidOperationException(Resources.RegionViewExistsException);

 ItemMetadata itemMetadata = new ItemMetadata(view);
 itemMetadata.IsActive = activate;
 if (!string.IsNullOrEmpty(name))
 {
  if (ItemMetadataCollection.FirstOrDefault(x => x.Name == name) != null)
   throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, Resources.RegionViewNameExistsException, name));
  itemMetadata.Name = name;
 }

 DependencyObject dependencyObject = view as DependencyObject;

 if (dependencyObject != null)
 {
  Regions.RegionManager.SetRegionManager(dependencyObject, regionManager);
 }

 ItemMetadataCollection.Add(itemMetadata);
}

This trickled into overriding the virtual Add:

public virtual IRegionManager Add(object view, string viewName, bool createRegionManagerScope, bool activated)
{
 IRegionManager regionManager = createRegionManagerScope ? this.RegionManager.CreateRegionManager() : this.RegionManager;
 InnerAdd(view, viewName, regionManager, activated);
 return regionManager;
}

Which resulted in a new method:

/// <summary>
/// Adds a new view to the region with a activated state of true
/// </summary>
/// <param name="view">The view to add.</param>
/// <returns>The <see cref="IRegionManager"/> that is set on the view if it is a <see cref="DependencyObject"/>. It will be the current region manager when using this overload.</returns>
public IRegionManager AddActivated(object view)
{
 return Add(view, null, false, true);
}

I took the safest route to resolve this issue, with the least amount of change.

The drawback results in implementation as the following:

IRegionManager manager = Container.Resolve<IRegionManager>();
Region region = manager.Regions[Shell.RegionId] as Region;
SingleView view = Container.Resolve<SingleView>();
if (region != null)
 region.AddActivated(view);

I have seen many posts regarding this small issue. The other consideration that came to mind were:
Defaulting the ItemMetadata.IsActive to true
Updating the interface to have 3 more Add method definitions with the activate parameter, to handle each existing case.

I do like your solution, but in case someone wanted more control, for whatever reason. (whine, whine!)

Andres Olivares

Aug 30, 2008 at 2:15 PM
Edited Aug 30, 2008 at 2:16 PM
[Andres] I do like your solution, but in case someone wanted more control, for whatever reason.

And I like your solution because there may be a good reason why the P&P team chose not to automatically activate the view, i.e., it is not a bug.  This at least offers two alternatives....
Oct 27, 2008 at 3:35 PM
Thanks I had the same problem ;)

I used Extension method as workaround:

public static IRegionManager Add(this IRegion region, object view, bool activate)
{
var returnValue = region.Add(view);
if (activate) region.Activate(view);
return returnValue;
}