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

ToolWindow Disappears And IGeneratedItemsFactory Does Not Always Create Custom Items

11 Answers 200 Views
Docking
This is a migrated thread and some comments may be shown as answers.
Beijerinc
Top achievements
Rank 1
Beijerinc asked on 06 Dec 2011, 03:21 PM
Hello,

I came across two bugs in the RadDocking system. I cannot create a bug report in the PITS because I get redirected to the general support page (perhaps because I am using the Telerik trial?).

1. In the example below I use a simple RadDocking. I dock a pane in a ToolWindow (Left or Right), undock it and dock it in the same ToolWindow (Top or Bottom). For some reason, the whole ToolWindow disappears after doing this.

2. In the second RadDocking, a custom IGeneratedItemsFactory is used to inject custom docking items. Somehow, after performing the same steps as before, a RadSplitContainer is inserted into the docking system instead of my custom MySplitContainer. This should not happen, because I am using a custom IGeneratedItemsFactory that should take care of it.

Here is the XAML for the MainPage:
<UserControl
    x:Class="RadDockingBugs.MainPage"
    xmlns:telerikdocking="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Docking"
    xmlns:dockingbugs="clr-namespace:RadDockingBugs"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
 
    <UserControl.Resources>
        <dockingbugs:DockingItemsFactory x:Key="ItemsFactory" />
    </UserControl.Resources>
 
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
 
        <!-- Perhaps both bugs are related? -->
        <telerikdocking:RadDocking Grid.Row="0">
            <telerikdocking:RadSplitContainer InitialPosition="FloatingDockable" telerikdocking:RadDocking.FloatingLocation="200,50">
                <telerikdocking:RadPaneGroup>
                    <telerikdocking:RadPane Header="Bug 1">
                        <telerikdocking:RadPane.Content>
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="Both panes and the ToolWindow will disappear if you do the following:" TextWrapping="Wrap" />
                                <TextBlock Text="- Take this pane, dock it left or right in 'Test Pane Number 1'." TextWrapping="Wrap" Margin="10 5 0 5" />
                                <TextBlock Text="- Take this pane out and dock it top or bottom in 'Test Pane Number 1', with or without intermediate drop and redrag." TextWrapping="Wrap" Margin="10 0 0 0" />
                            </StackPanel>
                        </telerikdocking:RadPane.Content>
                    </telerikdocking:RadPane>
                </telerikdocking:RadPaneGroup>
            </telerikdocking:RadSplitContainer>
            <telerikdocking:RadSplitContainer InitialPosition="FloatingDockable" telerikdocking:RadDocking.FloatingLocation="500,50">
                <telerikdocking:RadPaneGroup>
                    <telerikdocking:RadPane Header="Test Helper 1" Content="Test Pane Number 1" />
                </telerikdocking:RadPaneGroup>
            </telerikdocking:RadSplitContainer>
        </telerikdocking:RadDocking>
 
        <telerikdocking:RadDocking Grid.Row="1" GeneratedItemsFactory="{StaticResource ItemsFactory}">
            <telerikdocking:RadSplitContainer InitialPosition="FloatingDockable" telerikdocking:RadDocking.FloatingLocation="200,500">
                <telerikdocking:RadPaneGroup>
                    <telerikdocking:RadPane Header="Bug 2">
                        <telerikdocking:RadPane.Content>
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="With a custom IGeneratedItemsFactory, a RadSplitContainer is inserted instead of a MySplitContainer if you do the following:" TextWrapping="Wrap" />
                                <TextBlock Text="- Take this pane, dock it left or right in 'Test Pane Number 2'." TextWrapping="Wrap" Margin="10 5 0 5" />
                                <TextBlock Text="- Take this pane out and dock it top or bottom in 'Test Pane Number 2', with or without intermediate drop and redrag." TextWrapping="Wrap" Margin="10 0 0 0" />
                            </StackPanel>
                        </telerikdocking:RadPane.Content>
                    </telerikdocking:RadPane>
                </telerikdocking:RadPaneGroup>
            </telerikdocking:RadSplitContainer>
            <telerikdocking:RadSplitContainer InitialPosition="FloatingDockable" telerikdocking:RadDocking.FloatingLocation="500,500">
                <telerikdocking:RadPaneGroup>
                    <telerikdocking:RadPane Header="Test Helper 2" Content="Test Pane Number 2" />
                </telerikdocking:RadPaneGroup>
            </telerikdocking:RadSplitContainer>
        </telerikdocking:RadDocking>
    </Grid>
</UserControl>

Here is the code for the classes that are used to reproduce the bugs:
public class DockingItemsFactory : IGeneratedItemsFactory
{
    #region Factory Methods
    public ToolWindow CreateToolWindow()
    {
        return new MyToolWindow();
    }
 
    public RadSplitContainer CreateSplitContainer()
    {
        return new MySplitContainer();
    }
 
    public RadPaneGroup CreatePaneGroup()
    {
        return new MyPaneGroup();
    }
    #endregion
}
 
public class MyToolWindow : ToolWindow
{
    #region Events
    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);
 
        // This is a scenario I am using in another project. I need to know if a docking operation has occurred, so I use custom
        // split containers and pane groups that have ItemsChanged events. You can imagine the problem when a RadSplitContainer
        // is found instead of a MySplitContainer. I have to transfer the content (and style properties) to a new MySplitContainer,
        // detach the RadSplitContainer from its parent and substitute it with the MySplitContainer. In the mean time, I have to
        // be careful not to trigger an OnContentChanged or ItemsChanged event, to prevent looping.
        MySplitContainer oldSplitContainer = (MySplitContainer)oldContent;
        MySplitContainer newSplitContainer = (MySplitContainer)newContent;
 
        if ( oldSplitContainer != null)
        {
            oldSplitContainer.ItemsChanged -= MySplitContainer_ItemsChangedHandler;
        }
 
        if (newSplitContainer != null)
        {
            newSplitContainer.ItemsChanged += MySplitContainer_ItemsChangedHandler;
        }
    }
 
    private void MySplitContainer_ItemsChangedHandler(object sender, EventArgs e)
    {
        MySplitContainer splitContainer = (MySplitContainer)sender;
 
        // If there is any child split container that is not a MySplitContainer but -is- a RadSplitContainer, an error in the ToolWindow
        // children buildup process must have occurred.
        if (splitContainer.Items.Where(x => !(x is MySplitContainer) && x is RadSplitContainer).Any())
        {
            throw new InvalidCastException("A RadSplitContainer sneaked into the MyToolWindow children!");
        }
    }
    #endregion
}
 
public class MySplitContainer : RadSplitContainer
{
    #region Events
    public event EventHandler ItemsChanged;
 
    protected void NotifyItemsChanged()
    {
        if (ItemsChanged != null)
        {
            ItemsChanged(this, new EventArgs());
        }
    }
 
    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);
 
        NotifyItemsChanged();
    }
    #endregion
}
 
public class MyPaneGroup : RadPaneGroup
{
}

I used Telerik RadControls Q3 2011 to reproduce the bugs.

Maybe the two bugs are related, seeing as they involve the same steps to reproduce them. Anyways, the second bug in particular is bothering me because I have to do a lot of work to correct for its behavior (I have to transfer the content and style properties of the RadSplitContainer to a new MySplitContainer, unhook the RadSplitContainer from its parent, hook up the MySplitContainer to that parent and try not to cause an OnContentChanged or ItemsChanged event in the process).

I hope I have provided enough information.

Kind regards,
Beijerinc

11 Answers, 1 is accepted

Sort by
0
Beijerinc
Top achievements
Rank 1
answered on 07 Dec 2011, 01:58 PM
Hello,

I have found another 2 bugs. Set the first RadDocking's "HasDocumentHost" property to false and insert the following XAML into the first RadDocking control to display the issues:
<telerikdocking:RadSplitContainer InitialPosition="DockedBottom" telerikdocking:RadDocking.FloatingLocation="800,50">
    <telerikdocking:RadPaneGroup Height="150">
        <telerikdocking:RadPane Header="Bug 3 and 4" IsPinned="False">
            <telerikdocking:RadPane.Content>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="An unspecified and unhandled ArgumentException will occur if you do the following:" TextWrapping="Wrap" />
                    <TextBlock Text="- Expand this pane (which you have already done, otherwise you cannot read this)." TextWrapping="Wrap" Margin="10 5 0 5" />
                    <TextBlock Text="- Resize this pane by dragging the top border of this pane up or down." TextWrapping="Wrap" Margin="10 0 0 5" />
                    <TextBlock Text="This bug occurs when there is no document host (HasDocumentHost='False'), the pane is unpinned and the pane is resized. Please note that to make the drag handle available, the RadPaneGroup has been given a height. If this is not done, the drag handle will exceed the screen bounds, because the size of the tab button that expands the pane has not been taken into account when determining the size of the pinned pane. To prove the height has nothing to do with the bug, another pane can be docked opposite from this pane to automatically restrict the size of this pane to half the docking area." TextWrapping="Wrap" />
                </StackPanel>
            </telerikdocking:RadPane.Content>
        </telerikdocking:RadPane>
    </telerikdocking:RadPaneGroup>
</telerikdocking:RadSplitContainer>

When an unpinned pane is resized in a RadDocking host that has no DocumentHost, an unhandled ArgumentException is thrown somewhere. The StackTrace of the exception is pretty much empty, because the exception is caught by Silverlight and used to call the UnhandledException event handler in the Application class.

The second bug is that the size of the tab button expanding the unpinned pane is not taken into account when setting the size of the pane. This makes the pane too large and, in a full screen RadDocking, will make the header of the pane unreadable. Also, the resize drag handle is unusable because it is placed outside the bounds of the screen (outside of the RadDocking, technically).

I hope I have provided enough information.

Kind regards,
Beijerinc
0
Beijerinc
Top achievements
Rank 1
answered on 08 Dec 2011, 09:51 AM

Hello,

The fifth bug I have found is that the Show event will not fire. The XAML below will add a pane to the first RadDocking to illustrate the bug and the code below will add an event handler to the Show event of the RadDocking.

Add the following XAML to the first RadDocking:

<telerikdocking:RadSplitContainer InitialPosition="FloatingDockable" telerikdocking:RadDocking.FloatingLocation="800,50">
    <telerikdocking:RadPaneGroup>
        <telerikdocking:RadPane Header="Bug 5">
            <telerikdocking:RadPane.Content>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="The Show event will not fire. If the event fires, a message box will be shown. To test this bug, do the following:" TextWrapping="Wrap" />
                    <TextBlock Text="- The Show event should fire once for every pane already opened when the example starts." TextWrapping="Wrap" Margin="10 5 0 5" />
                    <TextBlock Text="- Click the button below to create and display a new pane. This should also fire the Show event." TextWrapping="Wrap" Margin="10 0 0 5" />
                    <Button Content="Show Pane" Margin="100 0 10 0" Click="ShowPaneButton_ClickHandler" />
                </StackPanel>
            </telerikdocking:RadPane.Content>
         </telerikdocking:RadPane>
     </telerikdocking:RadPaneGroup>
</telerikdocking:RadSplitContainer>

Add the following attributes to the first RadDocking:

x:Name="RadDocking1" Show="RadDocking_ShowHandler"

And add the following code to the control hosting the RadDocking:

#region Events
private void RadDocking_ShowHandler(object sender, StateChangeEventArgs e)
{
    MessageBox.Show("The Show event of the RadDocking control fired.", "RadDocking Show Event", MessageBoxButton.OK);
}
 
private void ShowPaneButton_ClickHandler(object sender, RoutedEventArgs e)
{
    RadPane pane = new RadPane { Header = "Test Helper 3", Content = "Test Pane Number 3" };
    RadPaneGroup paneGroup = new RadPaneGroup();
    RadSplitContainer splitContainer = new RadSplitContainer { InitialPosition = DockState.FloatingDockable };
 
    RadDocking.SetFloatingLocation( splitContainer, new Point( 1100, 50 ) );
 
    splitContainer.Items.Add( paneGroup );
    paneGroup.Items.Add( pane );
 
    RadDocking1.Items.Add( splitContainer );
}
#endregion

The message box being opened in the Show event handler should be displayed at least 3 times upon startup (once for every pane already opened). When a new pane is opened by clicking the button in the XAML pane 'Bug 5', the Show event will not fire. The Close event does fire, however I do not have proof of that inside this example. Perhaps something was left out when restructuring the docking system in the Q3 2011 version.

I hope I have provided enough information.

Kind regards,
Beijerinc

0
Konstantina
Telerik team
answered on 09 Dec 2011, 02:02 PM
Hello Beijerinc,

Thank you for your feedback.

I will answer you point-by-point:
1) We confirm that this is a bug. I have logged it in PITS - you can view it here. You can track its status and see when it is going to be fixed.
2) The RadPaneGroups don't support Height. Only root level SplitContainers support absolute sizing. However, the exception is not expected. I have logged it in PITS also - you can view it here. As a work-around I can suggest you to put one more SplitContainer around the PaneGroup and set the Height to it.
3) The Show event fires when a hidden pane is shown. That is why is not firing when you are adding new panes.

Hope this information helps. Your Telerik points have been updated for your involvement.

Kind regards,
Konstantina
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Beijerinc
Top achievements
Rank 1
answered on 09 Dec 2011, 02:47 PM
Hello Konstantina,

Thank you for responding, I am pleased to see Telerik taking interest in the issues. I think you overlooked some things in the posts above:
 - While using a custom IGeneratedItemsFactory, on some occasions (reproducable), a non-custom split container is inserted in the visual sub tree of the custom toolwindow.
 - The Height property being set on the RadGroupPane is merely to allow users to drag/resize the unpinned pane. The exception occurs because the pane is resized by a user and there is no document host.
 - I set the Height on the RadPaneGroup because setting the Height on the parent RadSplitContainer does not have any effect. If you set the Height on the RadSplitContainer instead of the RadPaneGroup, the pane will be the same size as the docking host. The workaround you suggested works though, thank you.

May I suggest another improvement? Setting the HasDocumentHost property to false screws up the AutoHide area's, because the document host is collapsed and the AutoHide area's are no longer restricted by anything. I can't imagine a scenario where a developer would want the AutoHide area's to behave like that, because the AutoHide area's are not "toolbox" area's anymore. If you do not set the Visibility property to Collapsed, but rather the Opacity to 0.0, the AutoHide area's will still behave like they should and docking in the center of the RadDocking is still disabled.
Now, when I want to disable docking in the document host, I have to handle the PreviewShowCompass event and disable the center compass indicator. Though also a solution, I think the HasDocumentHost property implies this behavior.

Konstantina, you said the Show event is only fired when hidden panes are shown. Is there I way I can track that new panes are opened in a RadDocking, or should I just override the OnItemsChanged and throw a public ItemsChanged event?

Kind regards,
Beijerinc
0
Konstantina
Telerik team
answered on 14 Dec 2011, 01:59 PM
Hello Beijerinc,

The GenerateItemsFactory is not substituting the SplitContainers. The ones you receive that are not of type MySplitContainer are the defined in xaml.
As for the AutoHideArea - I have cerated a PITS item, so that you can vote for this feature. If it receives enough votes, we will consider implementing it.

Greetings,
Konstantina
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Beijerinc
Top achievements
Rank 1
answered on 14 Dec 2011, 02:11 PM
Hello Konstantina,

Thank you for your response.

Konstantina, you said the Show event is only fired when hidden panes are shown. Is there I way I can track that new panes are opened in a RadDocking, or should I just override the OnItemsChanged and throw a public ItemsChanged event?
I have already overridden the OnItemsChanged event to throw my own "PaneShow" event, but my event also fires when a pane is docked (as the pane is rewrapped in a split container and then readded to the items collection). There must be a better way.

Also, it seems that when a pane is docked, an empty split container is left in the items collection. After a lot of docking and undocking, the RadDocking control will probably become slower and take up more memory. You might want to look into this. I am not sure if this is a bug specific to my implementation, the use of the IGeneratedItemsFactory or if this bug always occurs.

Kind regards,
Beijerinc
0
Beijerinc
Top achievements
Rank 1
answered on 14 Dec 2011, 03:23 PM
Hello Konstantina,

Could you tell me in which controls a RadSplitContainer is used (in the XAML) so that I can skin them to use my MySplitContainer?

Thank you in advance,
Beijerinc
0
Konstantina
Telerik team
answered on 19 Dec 2011, 10:18 AM
Hello Beijerinc,

There is no event for tracking the added panes in the Docking control. Your solution seems reasonable. Only the panes are moved, the SplitContainers and the RadPaneGroups stay at one place. This is how the Docking control is working. We have tested the performance of the Docking control and we didn't encounter any performance issues regarding the creating of new SplitContainers and PaneGroups.
As for the XAML SplitContainers - I meant the ones you have defined in XAML, as I can tell from the code you have send in one of the previous posts. Since there are some added to the Docking, using the GeneratedItemsFactory won't replace them with the new ones.

Best wishes,
Konstantina
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Beijerinc
Top achievements
Rank 1
answered on 19 Dec 2011, 10:30 AM
Hello Konstantina,

It appears you are right, I had some RadSplitContainers added to the docking. However, I have changed the RadSplitContainers and RadPaneGroups to MySplitContainers and MyPaneGroups, and somehow the bug still occurs. The strange thing is, it is reproducable by docking two panes first left or right, then top or bottom. By the way, the RadSplitContainer that sneaks into the object tree is not the top most parent, but one below.

Could you check if the bug is reproducable by creating a project with the post's code and replacing the RadSplitContainers and RadPaneGroups in the bottom RadDocking?

Thank you in advance,
Beijerinc
0
Konstantina
Telerik team
answered on 20 Dec 2011, 03:47 PM
Hello Beijerinc,

Sorry, but I already tried to reproduce it, but to no avail. Could you please open a support ticket and send us your project, in which we can observe this issue. In that way we will be able to run it locally and debug it in order to find the source of the problem.

Thank you in advance.

Greetings,
Konstantina
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Beijerinc
Top achievements
Rank 1
answered on 21 Dec 2011, 09:44 AM
Hello Konstantina,

I have opened a support ticket and attached a project that will help you reproduce the bug. You can find it here: http://www.telerik.com/account/support-tickets/view-ticket.aspx?threadid=494953.

Please note that an exception is thrown by the MyToolWindow class if the bug occurs. Because this exception is thrown in an event handler, this will unfortunately result in an IE error window instead of a debugger break.

I hope you are able to reproduce the bug and find its cause,
Beijerinc

PS: I apologize for not opening a support ticket in the first place, I was not aware of the possibility. I believed support tickets where made in PITS, yet I could not find a way to upload a project. Again, my apoligies. Thank you for helping me.
Tags
Docking
Asked by
Beijerinc
Top achievements
Rank 1
Answers by
Beijerinc
Top achievements
Rank 1
Konstantina
Telerik team
Share this question
or