Cider is not working with Region Manager

Dec 7, 2008 at 5:51 PM
I have the following XAML in Shell.xaml.

<Window x:Class="CALApplication.Desktop.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"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ItemsControl cal:RegionManager.RegionName="MainRegion" />

    </Grid>
</Window>


I'm getting the following error and the designer is not working.  How can I fix this issue?

Error    1    Value 'MainRegion' cannot be assigned to property 'RegionName'. Object reference not set to an instance of an object.    C:\Michael Sync\CompositeWPF\V2 Drop 7\Prismv2D7Sample\CALApplication.Shell\CALApplication.Desktop\Shell.xaml    7    23    CALApplication.Desktop

Dec 9, 2008 at 12:15 AM
We're not alone on this error Michaelsync.  Looks like this XAML designer issue became more prevelant after Visual Studio SP1 - my workaround follows:

        <Border Margin="10,5,10,10" Grid.Row="1" CornerRadius="4,4,4,4" BorderBrush="#FF0F68A6" Background="#FFFCFCFC" BorderThickness="2,2,2,2" Width="Auto" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <StackPanel Width="Auto" Height="Auto" Margin="10,10,10,10">
                <ItemsControl x:Name="MainRegion"
                              Width="Auto"
                              Height="Auto"
                              HorizontalAlignment="Stretch"
                              VerticalAlignment="Stretch"/>
            </StackPanel>
        </Border>

And my code behind looks as follows:

    public partial class Shell : UserControl
    {
        public Shell()
        {
            InitializeComponent();

            RegionManager.SetRegionName(MainRegion, "MainRegion");
        }
    }

Dec 16, 2008 at 11:33 PM
Thanks for reporting this issue. This should be fixed in the next drop.

Julian Dominguez
http://blogs.southworks.net/jdominguez
Dec 17, 2008 at 2:28 PM
@Julian,  great news - do you have a workaround we can use before then?  Our sprint will be over the end of this month and I'm currently cranking out the UI infrastructure (many many views) using this workaround.   No worries if it isn't practical - I'll schedule for refactoring after the next drop (our team is new to Silverlight and the Presentation pattern so I want to keep things consistent with documentation).
Dec 17, 2008 at 2:42 PM
Thanks, Julian and Billkrat,

You guys should do something about Project Linker too. I'm not able to install it in my office machine but i can install in my laptop.. it's very strange. wanna know the reason.


Dec 19, 2008 at 3:08 PM
@Bill, there will be a drop soon (probably today) with the bug fix for the RegionName. So look for that drop, sorry I didn't read your reply before.
Dec 22, 2008 at 1:44 PM
Regions work like a champ and I can now use Expression Blend while coding properly!  Thanks!!
Dec 26, 2008 at 5:21 PM
Hi Billkrat,

>> RegionManager.SetRegionName(MainRegion, "MainRegion");

When does that new region get registered? Is it right after that line?

Can I called like that?

RegionManager.SetRegionName(MainRegion, "MainRegion");

IRegion tabRegion = region.RegionManager.Regions["MainRegion"]

tab.Region.Add(v);


Dec 27, 2008 at 11:53 AM
I use TopDown composition so the only thing in my code-behind file was the RegionManager.SetRegionName(MainRegion, "MainRegion").    My module and presenters wired up the applicable views to their respective regions (ref: http://www.CodePlex.com/SDMS).  

I would raise an eyebrow on the above code because it would  suggest that the View's code-behind file would be doing the wire-up - not a good practice.

Fortunately, we can now define our regions in XAML :)
Dec 27, 2008 at 1:51 PM
I got this question when I'm trying to solve this problem.. http://www.codeplex.com/CompositeWPF/Thread/View.aspx?ThreadId=42843

We have the following in TabGroupPaneRegionAdapter of CompositeWPFContrib.Composite.Wpf.Infragistics.

private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, TabGroupPane regionTarget)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                //Add content panes for each associated view.
                foreach (object item in e.NewItems)
                {
                    UIElement view = item as UIElement;

                    if (view != null)
                    {
                        ContentPane newContentPane = new ContentPane();
                        newContentPane.Content = item;

                        //if associated view has metadata then apply it.
                        if (view.GetTabGroupPaneMetadata() != null) {
                            newContentPane.Header = (view.GetTabGroupPaneMetadata()).Header;
                        }
                       
                        //When contentPane is closed remove the associated region
                        newContentPane.Closed += delegate(object contentPaneSender, PaneClosedEventArgs args)
                        {
                            OnContentPaneClosed((ContentPane)contentPaneSender, args, region);
                        };


                        regionTarget.Items.Add(newContentPane);
                    }
                }
            }
            else
            {
                if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    //Associated View has been removed => remove the associated ContentPane from XamDockManager
                    XamDockManager xamDockManager = regionTarget.FindDockManager();
                    IEnumerable<ContentPane> contentPanes = xamDockManager.GetPanes(PaneNavigationOrder.VisibleOrder);

                    foreach (ContentPane contentPane in contentPanes)
                    {
                        if (e.OldItems.Contains(contentPane.Content))
                        {
                            contentPane.Content = null;
                            contentPane.CloseAction = PaneCloseAction.RemovePane;
                            contentPane.ExecuteCommand(ContentPaneCommands.Close);
                        }
                    }


                }
            }
        }

We can add and activate the view as below in Module.

IRegion contentRegion = this.regionManager.Regions[RegionNames.ContentRegion];

                IView1 view = contentRegion.GetView(typeof(View1).FullName) as IView1;

                if (view == null) {
                    ITabGroupPaneMetadata tabGroupPaneMetadata = new TabGroupPaneMetadata() {
                        Header = menuText,
                        ViewName = typeof(TView).FullName
                    };

                    view = container.Resolve<IView1>();
                    view.ViewModel = container.Resolve<IView1ViewModel>();


                    (view as DependencyObject).SetTabGroupPaneMetadata(tabGroupPaneMetadata);

                    contentRegion.Add(view, typeof(View1).FullName, true);

                }
contentRegion.Activate(view);

What I want to do is that ~
  • Switch the View1 to View2
  • Change the tab titile

If View2 in under the same module, I can do as below.

var view2 = container.Resolve<View2>();
                        ((Infragistics.Windows.DockManager.ContentPane)System.Windows.Media.VisualTreeHelper.GetParent(System.Windows.Media.VisualTreeHelper.GetParent(System.Windows.Media.VisualTreeHelper.GetParent(System.Windows.Media.VisualTreeHelper.GetParent(System.Windows.Media.VisualTreeHelper.GetParent(view as DependencyObject)))))).Content = c;

It works. I won't be able to call the View1 next time. The visual parent of View1 has been broken after calling this line. (I cant change the header text but this is different story that I'm going to discuss later. )

Currently, View2 is under different module and those modules dont have the strong reference. so, its hard to get the instance of View2. I don't want to pass the instance of view .

So, I'm thinking to add one scoped region in TabGroupPaneRegionAdapter so that I can show the View2 by using region manager. The sequence will be like ~

1. Add View1 with TabGroupPane
2. Create the region called "View1Region" inside the TabGroupPane
3. Let's say there is a button in View1. I will publish the event with region name from Btn-Click.
4. View2 will be subscribed this event.
5. View2 will get the region name from event.
6. View2 will show itself on that region.


That's why I'm trying to modify a bit in TabGroupPaneRegionAdapter. I tried to register a region in tab. If I want to swith the view, I will tell another view  "View2" to show on that region.

private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, TabGroupPane regionTarget)
        {
if (e.Action == NotifyCollectionChangedAction.Add)
            {
                //Add content panes for each associated view.
                foreach (object item in e.NewItems)
                {
                    UIElement view = item as UIElement;

                    if (view != null)
                    {
                        ContentPane newContentPane = new ContentPane();

                        //if associated view has metadata then apply it.
                        if (view.GetTabGroupPaneMetadata() != null) {
                            newContentPane.Header = (view.GetTabGroupPaneMetadata()).Header;
                            RegionManager.SetRegionName(newContentPane, (view.GetTabGroupPaneMetadata()).ViewName);
                        }

                        
                        //newContentPane.Content = item; // I CAN'T set the content after setting it as a region. So, I'm trying to get the region that I just register.
                        
                       

                        //When contentPane is closed remove the associated region
                        newContentPane.Closed += delegate(object contentPaneSender, PaneClosedEventArgs args)
                        {
                            OnContentPaneClosed((ContentPane)contentPaneSender, args, region);
                        };


                        regionTarget.Items.Add(newContentPane);
                    }
                }
            }

.......
.......

But it doesnt' work. :(

Jun 15, 2009 at 12:48 AM

Hi

Out of curiosity has any defined a Region in visual studio 2010?

I have done it today but get the same error as the beginning of this post. Object reference not set to an instance of an object.

Here is my code:

<UserControl x:Class="SilverPoint.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Regions="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"
    mc:Ignorable="d" Height="300" Width="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <ItemsControl Name="MainRegion" Regions:RegionManager.RegionName="MainRegion"  />       
    </Grid>
</UserControl>

Any ideas?

Thanks

Mike