Prism load view in documenthost (region) problem

3 posts, 1 answers
  1. Guillaume
    Guillaume avatar
    12 posts
    Member since:
    May 2013

    Posted 27 May 2013 Link to this post

    Hi everyone,

    I'm using PRISM with MEF for modularity with RadDocking Telerik component to display my views into dock.

    On my application, I have a Shell with a dockmenu on the left, and a documenthost on the center, here is the Shell.xaml :
    <telerik:RadDocking PreviewClose="RadDocking_PreviewClose" x:Name="dock">
        <telerik:RadDocking.DocumentHost>
            <telerik:RadSplitContainer >
                <telerik:RadPaneGroup prism:RegionManager.RegionName="{x:Static const:RegionConstants.CentralRegionName}" x:Name="centralGroup"  />
            </telerik:RadSplitContainer>
        </telerik:RadDocking.DocumentHost>
     
        <telerik:RadSplitContainer x:Name="leftContainer" InitialPosition="DockedLeft">
            <!-- Menu -->
            <telerik:RadPaneGroup x:Name="MenuGroup">
                <telerik:RadPane x:Name="MenuPanel" Header="Menu" CanUserClose="False">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
     
                        <telerik:RadTreeView x:Name="principalMenuTreeView" Grid.Row="1"
                                             VerticalAlignment="Stretch"
                                             IsLineEnabled="True" ScrollViewer.HorizontalScrollBarVisibility="Auto"
                                             SelectionMode="Single" IsEditable="False" IsDragDropEnabled="True">
                            <telerik:RadTreeViewItem Header="Monitoring" IsExpanded="True">
                                <telerik:RadTreeViewItem Header="All Customers"
                                                         Command="{Binding LoadViewCommand}"
                                                         CommandParameter="{x:Static const:ViewConstants.AllCustomersView}" />
                            </telerik:RadTreeViewItem>
     
                        </telerik:RadTreeView>
                    </Grid>
                </telerik:RadPane>
            </telerik:RadPaneGroup>
        </telerik:RadSplitContainer>
    </telerik:RadDocking>


    I'm using a command in my ShellViewModel to add view in the DocumentHost region, it works correctly :
    private void DisplayViewCommand(object viewName)
    {
        IRegion region = this.regionManager.Regions[RegionConstants.CentralRegionName];
     
        object view = null;
        switch (viewName as string)
        {
            case ViewConstants.AllCustomersView:
                view = ServiceLocator.Current.GetInstance<AllCustomersView>();
                break;
            default:
                break;
        }
     
        if (region.Views.Contains(view))
        {
            region.Remove(view);
        }
     
        region.Add(view);
        region.Activate(view);
    }


    I overrided the close panel button to remove the view from the Region, it works too (Shell.xaml.cs) :

    private void RadDocking_PreviewClose(object sender, StateChangeEventArgs e)
    {
        if (e.Panes != null && e.Panes.Count() > 0)
        {
            RadPane toDelete = e.Panes.FirstOrDefault();
            IRegion mainRegion = this.regionManager.Regions[RegionConstants.CentralRegionName];
     
            if (mainRegion.Views.Contains(toDelete))
            {
                mainRegion.Remove(toDelete);
            }
        }
     
        e.Handled = true;
    }


    But, when I drag this pane out of that group (to make it float), and I try to launch the command to load the view again, it prompt me an error in the RadPaneGroupRegionAdapter.cs, on the line "regionTarget.Items.Add(view);"  :

    Element already has a logical parent. It must be detached from the old parent before it is attached to a new one.
    case NotifyCollectionChangedAction.Reset:
        regionTarget
                    .EnumeratePanes()
                    .ToList()
                    .ForEach(p => p.RemoveFromParent());
        foreach (object view in region.Views)
        {
            regionTarget.Items.Add(view); /!\ On this line, the exception occurs
        }
        break;

    Maybe I forgot something ?
    In advance, thanks for your help.

    Regards,
    Guillaume
  2. Answer
    Charles
    Charles avatar
    41 posts
    Member since:
    Mar 2012

    Posted 27 May 2013 Link to this post

    Hi Guillaume

    This is similar to my issue you commented on.

    The cause is that when a user drags an item from a group, it is removed from that group's item collection (referred in the last part of your code as 'regionTarget.EnumeratePanes()' or 'regionTarget.Items').

    When you are removing panes, you will need to remove them from wherever in the RadDocking control they exist, which may not necessarily be in the original RadPaneGroup they were added to.

    It seems the 'views' you are adding are straight RadPane's (in mine, they are normal UserControls and the adapter wraps them in a RadPane).  If this is the case, the solution is a little more straightforward.  The reset and remove cases would be something like this (untested!):
    case NotifyCollectionChangedAction.Remove:
        foreach (RadPane pane in e.OldItems)
        {
            pane.RemoveFromParent();
        }
        break;
    case NotifyCollectionChangedAction.Reset:
        foreach (RadPane pane in region.Views)
        {
            pane.RemoveFromParent();
            regionTarget.Items.Add(pane);
        }
        break;

  3. UI for WPF is Visual Studio 2017 Ready
  4. Guillaume
    Guillaume avatar
    12 posts
    Member since:
    May 2013

    Posted 27 May 2013 Link to this post

    Hi Charles

    You're right, I'm using RadPane as views in my modules.
    Thanks for your solution, it works perfectly !

    Regards,
    Guillaume
Back to Top