This is a migrated thread and some comments may be shown as answers.

Prism load view in documenthost (region) problem

2 Answers 112 Views
Docking
This is a migrated thread and some comments may be shown as answers.
Guillaume
Top achievements
Rank 1
Guillaume asked on 27 May 2013, 07:43 AM
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 Answers, 1 is accepted

Sort by
0
Accepted
Charles
Top achievements
Rank 1
answered on 27 May 2013, 10:23 AM
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;

0
Guillaume
Top achievements
Rank 1
answered on 27 May 2013, 12:20 PM
Hi Charles

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

Regards,
Guillaume
Tags
Docking
Asked by
Guillaume
Top achievements
Rank 1
Answers by
Charles
Top achievements
Rank 1
Guillaume
Top achievements
Rank 1
Share this question
or