Dragablz icon indicating copy to clipboard operation
Dragablz copied to clipboard

Error when trying to split a layout: 'Instance not within any layout'

Open AnotherKiwi opened this issue 8 years ago • 4 comments

I'm getting an 'Instance not within any layout' error when I try to split the root layout defined in my main window's XAML.

The main window is declared as:

<catel:DataWindow x:Class="Views.HerbertWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:SRH.Herbert"
        xmlns:h="clr-namespace:SRH.Herbert.Helpers"
        xmlns:uc="clr-namespace:SRH.Herbert.UserControls"
        xmlns:vm="clr-namespace:SRH.Herbert.ViewModels"
        xmlns:catel="http://catel.codeplex.com"
        xmlns:dragablz="http://dragablz.net/winfx/xaml/dragablz"
        xmlns:dockablz="http://dragablz.net/winfx/xaml/dockablz"
        mc:Ignorable="d"
        Title="{Binding Title}" 
        Left="{Binding Left, Mode=TwoWay}" Top="{Binding Top, Mode=TwoWay}" 
        Height="{Binding Height, Mode=TwoWay}" Width="{Binding Width, Mode=TwoWay}"
        MinHeight="{Binding MinHeight}" MinWidth="{Binding MinWidth}" 
        ShowInTaskbar="True" ResizeMode="CanResizeWithGrip" SizeToContent="Manual" 
        WindowStartupLocation="Manual" WindowState="Normal">

    <!-- Resources -->
    <catel:DataWindow.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <DataTemplate DataType="{x:Type dragablz:HeaderedItemViewModel}">
                <ContentControl Content="{Binding Content}" Margin="4 4 4 4" FontSize="14" />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm:CustomTabHeaderViewModel}">
                <uc:CustomTabHeader />
            </DataTemplate>
            <dragablz:InterTabController x:Key="InterTabController" 
                                         x:Shared="False" 
                                         InterTabClient="{Binding InterTabClient}" 
                                         Partition="2AE89D18-F236-4D20-9605-6C03319038E6" />

            <Style TargetType="{x:Type dragablz:TabablzControl}" x:Key="TabablzControlStyle">
                <Setter Property="NewItemFactory" Value="{x:Static h:NewTabItem.Factory}" />
                <Setter Property="ItemsSource" Value="{Binding Items}" />
                <Setter Property="ClosingItemCallback" Value="{Binding ClosingTabItemHandler}" />
                <Setter Property="ShowDefaultAddButton" Value="True" />
                <Setter Property="ShowDefaultCloseButton" Value="True" />
                <Setter Property="AdjacentHeaderItemOffset" Value="-10" />
                <Setter Property="ItemContainerStyle" Value="{StaticResource TrapezoidDragableTabItemStyle}" />
                <Setter Property="HeaderMemberPath" Value="Header" />
                <Setter Property="InterTabController" Value="{StaticResource InterTabController}" />
                <Setter Property="Margin" Value="0 8 0 0" />
            </Style>
        </ResourceDictionary>
    </catel:DataWindow.Resources>

    <DockPanel>
        <DockPanel DockPanel.Dock="Top" KeyboardNavigation.TabNavigation="None">
            <Menu KeyboardNavigation.TabNavigation="Cycle">
                <MenuItem Header="_File">
                    <MenuItem Header="{Binding CloseMenuItemHeader}" x:Name="CloseMenuItem" Command="{Binding CloseWindow}" />
                </MenuItem>
                <MenuItem Header="_Edit" />
                <MenuItem Header="_Options" />
                <MenuItem Header="_Help" />
            </Menu>
        </DockPanel>

        <Grid Margin="2">
            <Grid.RowDefinitions>
                <RowDefinition x:Name="RibbonRow" Height="{Binding RibbonRowHeight}"></RowDefinition>
                <RowDefinition x:Name="DragablzControlRow" Height="*"></RowDefinition>
                <RowDefinition x:Name="StatusBarRow" Height="{Binding StatusBarRowHeight}"></RowDefinition>
            </Grid.RowDefinitions>

            <!-- Ribbon definition --> 
            <Ribbon>
                <Button>Button 1</Button>
            </Ribbon>           

            <!-- StatusBar definition -->
            <StatusBar Grid.Row="2">
                <StatusBar.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" ></ColumnDefinition>
                                <ColumnDefinition Width="Auto" ></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </StatusBar.ItemsPanel>
                <TextBlock > Left Side</TextBlock>
                <StatusBarItem Grid.Column="3">
                    <TextBlock > Right Side</TextBlock>
                </StatusBarItem>
            </StatusBar>

            <dockablz:Layout Grid.Row="1" 
                             Partition="2AE89D18-F236-4D20-9605-6C03319038E6" 
                             x:Name="RootLayout"
                             IsFloatDropZoneEnabled="False">
                
                <!-- branch template lets dragablz create a new tab control after a window is split via docking -->
                <dockablz:Layout.BranchTemplate>
                    <DataTemplate>
                        <dragablz:TabablzControl Style="{StaticResource TabablzControlStyle}">
                            <dragablz:TabablzControl.InterTabController>
                                <dragablz:InterTabController InterTabClient="{Binding InterTabClient}" 
                                                             Partition="2AE89D18-F236-4D20-9605-6C03319038E6" />
                            </dragablz:TabablzControl.InterTabController>
                        </dragablz:TabablzControl>
                    </DataTemplate>
                </dockablz:Layout.BranchTemplate>
                
                <!-- a root, named tab control is needed, so when a tab is torn and a new window is created,
                     the new target tab control can be identified -->
                <dragablz:TabablzControl x:Name="InitialTabablzControl"
                                         FixedHeaderCount="1"
                                         ItemsSource="{Binding TabItemsSource}"
                                         Style="{StaticResource TabablzControlStyle}"
                                         AddLocationHint="After">
                    <dragablz:TabablzControl.InterTabController>
                        <dragablz:InterTabController InterTabClient="{Binding InterTabClient}" 
                                                     Partition="2AE89D18-F236-4D20-9605-6C03319038E6" />
                    </dragablz:TabablzControl.InterTabController>
                </dragablz:TabablzControl>
            </dockablz:Layout>
        </Grid>
    </DockPanel>
</catel:DataWindow>

I'm trying to create the split layout in my VB application's OnStartup event handler, using the following code:

    ' Instantiate the Herbert application.
    HerbertApp = New App()

    With HerbertApp
        ' Instantiate the main Herbert window.
        MainHerbertWindow = New HerbertWindow
        .MainWindow = MainHerbertWindow

        Dim myTabablzControl As TabablzControl = MainHerbertWindow.InitialTabablzControl
        Dim myLayout As Layout = MainHerbertWindow.RootLayout

        Dim newTabablzControl As TabablzControl = myLayout.Branch(myTabablzControl, Orientation.Vertical,
                                                                  False, 0.25).TabablzControl

VS throws the 'Instance not within any layout' error when it tries to execute the Branch(), despite myTabablzControl having RootLayout as its Parent (so it must be in a layout). I've tried doing the split in a TabablzControlProxy class, passing the initial TabablzControl to its constructor. However the result was the same. The error details are shown in this screenshot:

devenv_2017-02-26_16-11-25

If I comment out the lines with the call to Branch() my skeleton application window opens with the TabablzControl containing an HeaderedItemViewModel item that is added in its viewmodel (as shown below). I can add new items by clicking on the add tab item button, and I can tear off tabs and then dock them to the initial TabablzControl (which successfully creates splits in the layout).

herbert net vshost_2017-02-26_16-34-16

It's possible this 'Instance not within any layout' problem is somehow being caused by Catel, which I've just started using. When the type of the main window was System.Window instead of Catel.DataWindow I was able to split the initial TabablzControl by means of code similar to the above in a TabablzControlProxy class. However, I'm keen to keep using Catel if possible, so would really appreciate any suggestions of how to overcome this problem.

For example, is it possible to instantiate the Layout and its TabablzControl in code rather than in the main window XAML, and would that be likely to get around the problem?

Stephen

AnotherKiwi avatar Feb 26 '17 03:02 AnotherKiwi

Hi, Can you please post a small example GitHub repository.

ButchersBoy avatar Feb 26 '17 10:02 ButchersBoy

Hi Thanks for the quick response! I'm just putting one together and will post it soon.

AnotherKiwi avatar Feb 26 '17 16:02 AnotherKiwi

Hi I've posted a small test application that creates a window containing a Dragablz control, from which tabs can be torn off and then docked with the original control to create split layouts. An attempt to open the window with a split already performed using code in the OnStartup event handler fails, however. Any suggestions that get this functionality working will be greatly appreciated!

https://github.com/AnotherKiwi/Catel-and-Dragablz-Test

AnotherKiwi avatar Feb 27 '17 06:02 AnotherKiwi

Hi I've posted a small test application that creates a window containing a Dragablz control, from which tabs can be torn off and then docked with the original control to create split layouts. An attempt to open the window with a split already performed using code in the OnStartup event handler fails, however. Any suggestions that get this functionality working will be greatly appreciated!

https://github.com/AnotherKiwi/Catel-and-Dragablz-Test

Did you ever solve this issue?

speedyalibaba avatar Mar 11 '19 23:03 speedyalibaba