I am currently making a game engine editor with WPF in C#. I have decided to use GridSplitter components along with grids that contain column and row definitions. I have two grids, one for the top column definition (0) and one for the bottom column definition (1). In the top grid, I have some row definitions for placing 3 tab controls and 2 grid splitters in. I don't have any grid splitters or row definitions in the second row, only another tab control so that it can scale to the same screen width.
Here's my problem:
Whenever I go to use the left grid splitter to resize the left tab control in the top grid, this happens
Same thing happens if I try and scale the right tab control with the grid splitter
Here is my code:
<Window x:Class="Editor.MainWindow"
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:local="clr-namespace:Editor"
mc:Ignorable="d"
Title="Frostplay Engine 2020.1.0 - Level.frost - Project" Height="720" Width="1280" Background="#FF1E1E1E">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="3" />
<RowDefinition Height="250" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="3" /> <!-- 2: First Grid Splitter -->
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3" /> <!-- 4: Second Grid Splitter -->
<ColumnDefinition Width="3" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TabControl x:Name="TopLControl" Background="{x:Null}" BorderThickness="0">
<TabItem Header="Hierarchy" Style="{StaticResource CustomTabControl}" Foreground="White" FontSize="14">
<Grid Background="#FF3C3C3C"/>
</TabItem>
</TabControl>
<GridSplitter Grid.Column="2" Width="3" HorizontalAlignment="Stretch" Background="#FF282828" />
<TabControl x:Name="TopCControl" Grid.Column="3" Background="{x:Null}" BorderThickness="0">
<TabItem Header="Scene" Style="{StaticResource CustomTabControl}" Foreground="White" FontSize="14">
<Grid Background="#FF3C3C3C"/>
</TabItem>
<TabItem Header="Game" Style="{StaticResource CustomTabControl}" Foreground="White" FontSize="14">
<Grid Background="#FF3C3C3C"/>
</TabItem>
</TabControl>
<GridSplitter Grid.Column="4" Width="3" HorizontalAlignment="Stretch" Background="#FF282828" />
<TabControl x:Name="TopRightControl" Grid.Column="6" Background="{x:Null}" BorderThickness="0">
<TabItem Header="Inspector" Style="{StaticResource CustomTabControl}" Foreground="White" FontSize="14">
<Grid Background="#FF3C3C3C"/>
</TabItem>
</TabControl>
</Grid>
<GridSplitter Grid.Row="1" Height="3" HorizontalAlignment="Stretch" Background="#FF282828" />
<Grid Grid.Row="2">
<TabControl x:Name="BottomControl" Background="{x:Null}" BorderThickness="0">
<TabItem Header="Project" Style="{StaticResource CustomTabControl}" Foreground="White" FontSize="14">
<Grid Background="#FF3C3C3C"/>
</TabItem>
<TabItem Header="Console" Style="{StaticResource CustomTabControl}" Foreground="White" FontSize="14">
<Grid Background="#FF3C3C3C"/>
</TabItem>
</TabControl>
</Grid>
</Grid>
Does anybody know how I can fix it so that when I drag the left grid splitter to the left, the middle tab control scales to the left too, and when I move the right grid splitter to the right, the middle tab control scales to the right?
Thank you for reading! :)
This happens because the 3 ColumnDefinitions with Width="*" will have the same width all the time (that's the meaning of *, when width of one changes, all the others change too). You use 2 of Width="3" ColumnDefinitions for the GridSplitters. When you move the splitter, 1 of TabControl's width decreases, that causes the other TabControls to contract and those 2 unused ColumnDefinitions fill up the remaining space (Width="3" is overridden in this case).
Remove those unused ColumnDefinitions and adjust Grid.Column of the GridSplitters and TabControls accordingly.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<!-- remove this one <ColumnDefinition Width="3" /> -->
<ColumnDefinition Width="3" /> <!-- 2: First Grid Splitter -->
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3" /> <!-- 4: Second Grid Splitter -->
<!-- and this one <ColumnDefinition Width="3" /> -->
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
I guess you wanted those unused ColumnDefinitions to work as margin. Don't do this, set some margin on the TabControls instead.
Related
I have a simple app that has three columns in the window. In the middle column, I have a ListBox component.
What I want is the ListBox to stretch the full height of the column, but also be scrollable when it has a lot of stuff in it. Right now, it's not scrollable. I can fix this by adding a Height (e.g. Height="300") property to it, but then it won't stretch with the column anymore. What do I do?
<Window x:Class="UI.MainWindow"
<!-- window stuff -->
<Border Padding="10">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="150" MaxWidth="200" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- column 1 stuff -->
<StackPanel x:Name="LogLines" Grid.Column="1">
<StackPanel Orientation="Horizontal">
<Label>Search</Label>
<TextBox x:Name="Searchbox" Height="20" TextWrapping="Wrap" Text="TextBox" Width="120" />
<CheckBox x:Name="ErrorsOnlyCheckbox" HorizontalAlignment="Right">
Errors only
</CheckBox>
</StackPanel>
<ListBox
x:Name="LogLinesList"
ScrollViewer.CanContentScroll="True" />
</StackPanel>
<GridSplitter Grid.Column="1" Width="10" />
<!-- column 3 stuff -->
</Grid>
</StackPanel>
</Border>
</Window>
Container of your ListBox is StackPanel. StackPanel will increase regarding child controls. You should use another container, try to use Grid instead
<Grid x:Name="LogLines" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Width="Auto"/>
<RowDefinition Width="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
....
</StackPanel>
<ListBox Grid.Row="1"/>
</Grid>
I'm trying to hide a column in a Grid with a GridSplitter when a button is clicked (the button sets the visibility of all items in the third column to collapsed). If I don't move the GridSplitter it works properly and the third column disappear, but if I move the GridSplitter the content disappear but the others columns don't resize to fill the empty space.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="a" Width="*"/>
<ColumnDefinition x:Name="b" Width="3"/>
<ColumnDefinition x:Name="c" Width="Auto" MaxWidth="600"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Background="Green">
<Image Source="te/Dante.png" Height="Auto" Margin="0,128,2,71"/>
</Border>
<Button Grid.Column="0" Grid.Row="0" Width="30" Height="30" Margin="0,10,10,0" HorizontalAlignment="Right" VerticalAlignment="Top" Click="Button_Click"></Button>
<GridSplitter Width="5" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" ResizeDirection="Columns" HorizontalAlignment="Left" Background="White" BorderBrush="Black" BorderThickness="1,0" ResizeBehavior="PreviousAndCurrent"/>
<WrapPanel x:Name="wpC" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" MinWidth="300" HorizontalAlignment="Stretch" Background="Aqua" Panel.ZIndex="-1"></WrapPanel>
</Grid>
Here is an example of my problem (gif):
How can i solve this problem? Possibly respecting MVVM pattern.
The problem is simple, you set GridSplitter ResizeBehavior="PreviousAndCurrent", but previous grid column width is * and as soon as you move splitter its width units will be changed to absolute (so it will not be able to resize when 3d column width is changed).
Simply set GridSplitter ResizeBehavior="PreviousAndNext" to solve the problem. If you do so the splitter will modify width of 3d column, but shouldn't touch first one anymore.
Btw, instead of using button and click event you can utilize ToggleButton (which IsChecked is bound to Visibility of container with content you want to hide), see this answer. Using converters with pure xaml view is better MVVM than the one with some code behind and x:Name.
Right, you have few layout problems, here is a complete solution:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Background="Green" />
<ToggleButton x:Name="toggleButton"
Width="30"
Height="30"
Margin="0,10,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Top" />
<Grid Grid.Column="1"
Visibility="{Binding IsChecked, ElementName=toggleButton, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="300"
MinWidth="300"
MaxWidth="600" />
</Grid.ColumnDefinitions>
<GridSplitter Width="5"
ResizeBehavior="CurrentAndNext" />
<WrapPanel Grid.Column="1"
Background="Aqua" />
</Grid>
</Grid>
No need for code-behind, get converter from here.
Point are: 1) put splitter inside hide-able container 2) setup grid columns to have * and fixed width (splitter doesn't work well with auto columns).
Demo:
I have a typical MVVM structure. A mainwindow consists of some labels and a viewmodel (bound as ContentControl). This viewmodel has a listbox where I add entries. As the list grows the height of my viewmodel grows as well and thus the height of the whole application. Unfortunately the size doesn't stop at the edge of the screen and just grows out of the screen. I tried all the different size-restrictions on the mainwindow, the viewmodel is stretched in both dimensions.
Furthermore, I tried to get a scrollbar for the listbox but didn't succeed (or it's just there but not enabled if I force it.)
How can I restrict the maximal size to be the resolution of the screen (fullscreen) and get a scrollbar for the listbox when the size is reached?
€: Okay, here should be the relevant part of my code. I tried a fixed size of 1024x768 but even that doesn't work.
MainWindow.xaml
<Window x:Class="SWS.MainWindow"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Width="1024"
Height="768"
MaxWidth="1024"
MaxHeight="768">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
The ViewModel in question
<UserControl x:Class="SWS.Views.ProgramView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<Label Width="65" Content="{x:Static p:Resources.PrV_Number}" />
<Label Width="75" Content="{x:Static p:Resources.PrV_Weight}" />
<Label Width="55" Content="{x:Static p:Resources.PrV_Action}" />
<Label Content=" " />
</DockPanel>
<ListBox Grid.Row="1"
VerticalAlignment="Stretch"
ItemsSource="{Binding ParticleCollection}"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding ID}" Width="53" />
<TextBlock Text="{Binding Weight, StringFormat=F4}" Width="65" />
<TextBlock Text="{Binding Action}" Width="52" />
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
You need to set the row height to * on your Window for ContentControl and your ListBox in UserControl to fill available space than try to get what it needs.
This worked fine:
MainWindow.xaml:
<Window x:Class="SWS.MainWindow"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Width="1024"
Height="768"
MaxWidth="1024"
MaxHeight="768">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
and UserControl:
<UserControl x:Class="SWS.Views.ProgramView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
...
</Grid>
</UserControl>
Could also do this in a couple more ways:
In your Window you can just remove the <Grid.RowDefinitions>...<Grid.RowDefinitions> completely. The default behavior is what your looking for.
When you have more than 1 row you can either choose to specify Height="*" or just remove the Height Property from the RowDefinition
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
I have this:
<Window x:Class="ScrollTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="450"
Width="525">
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0"
Header="Stuff"
Height="200">
<TextBlock Text="Lots of controls go here"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</GroupBox>
<TabControl Grid.Row="1">
<TabItem Header="Main Tab">
<TextBox MinHeight="100"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
AcceptsReturn="True" />
</TabItem>
</TabControl>
</Grid>
</ScrollViewer>
</Window>
When I add too many rows into the TextBox, instead of the ScrollViewer of the TextBox being used, the box stretches and the outermost ScrollViewer is used. Can I prevent that without fixing the height of the TextBox or TabControl?
Update:
If I remove MinHeight on the TextBox and set MaxLines to 5, this is what I get:
If I added a 6th line, the scroll bars of the TextBox's ScrollViewer are used, but they still remain centered vertically in the TextBox control.
I was able to get close with this:
<Window x:Class="ScrollTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525">
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible"
x:Name="Base">
<Grid Height="{Binding ElementName=Base, Path=ActualHeight, Mode=OneWay}"
MinHeight="400">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0"
Header="Stuff"
Height="200">
<TextBlock Text="Lots of controls go here"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</GroupBox>
<TabControl Grid.Row="1">
<TabItem Header="Main Tab">
<Grid x:Name="myInnerGrid">
<TextBox MinHeight="100"
MaxHeight="{Binding ElementName=myInnerGrid, Path=ActualHeight, Mode=OneWay}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
AcceptsReturn="True" />
</Grid>
</TabItem>
</TabControl>
</Grid>
</ScrollViewer>
</Window>
Note the binding expression on height for the outside grid and on MaxHeight for the TextBox.
It's still not perfect in that you have to manually set the MinHeight that will trigger the outer most scrollbar. It's probably as close as WPF will allow without writing a new grid control.
The idea was found here:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/7b4b0c88-6b8f-4f07-aa8b-8e7018762388
Try looking at the MaxLines and MinLines Properties.
From above link:
Setting this property causes the text box to resize if the number of
visible lines exceeds the limit specified by MaxLines. This property
applies only to visible lines, and does not constrain the actual
number of lines. Depending on its configuration, a text box may
contain additional non-visible lines that are accessible by scrolling.
If the Height property is explicitly set on a TextBox, the MaxLines
and MinLines property values are ignored.
Try Changing:
<TextBox MinHeight="100"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
...
to
<TextBox MinLines="5"
MaxLines="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Edit: Give this a try. It is setting the VerticalContentAlignment of the TabItem. This will keep the text box at the top of the Tab, I also set the maxlines to what your available area is able to hold if you resize your form you may want to adjust that number to use all of the available space.
<TabItem Header="Main Tab" VerticalContentAlignment="Top" >
<TextBox
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
MinLines="8"
MaxLines="8"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
AcceptsReturn="True" />
</TabItem>
Edit:
After looking into it further, the reason the scrollbars are not showing up on the TextBox is because the TabControl and the TabItem are resizing to the size of the TextBox. What needs to be done is to have a limiting height set either on the TabControl, TabItem or TextBox this will allow the ScrollViewer to work for the TextBox.
I found that the best solution to this is to use the Border trick outlined here, applied both vertically and horizontally.
In the following example, a ScrollViewer contains a TextBox, where it is desired to have the TextBox fit all of the available space (vertically and horizontally), and have it scroll vertically before the parent ScrollViewer. The Border PlaceHolderBorder manages the Width of the TextBoxes as the parent window is resized. The Border DescriptionPlaceHolderBorder manages the Height of the Description TextBox as the parent control is resized, and the ScrollViewer of the TextBox kicks in before the parent control.
It is important to have Margins in the placeholder Borders.
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Background="{StaticResource ControlBackgroundBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Style="{DynamicResource LabelHeader}" Content="Company" />
<Label Grid.Row="1" Grid.Column="1" Style="{DynamicResource CompanyNameInput}" Content="{Binding CompanyNameLabel}" />
<Label Grid.Row="2" Grid.Column="1" Style="{DynamicResource DescriptionInput}" Content="{Binding DescriptionLabel}" />
<Border Name="PlaceHolderBorder" Grid.Column="2" Margin="7"/>
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding CompanyName}" MaxLength="255"/>
<Border Name="DescriptionPlaceHolderBorder" Grid.Row="2" Margin="7"/>
<TextBox Grid.Row="2" Grid.Column="2" Text="{Binding Description}" VerticalScrollBarVisibility="Auto"
TextAlignment="Left" TextWrapping="Wrap" AcceptsReturn="True" MinHeight="60"
Width="{Binding ElementName=PlaceHolderBorder, Path=ActualWidth}"
Height="{Binding ElementName=DescriptionPlaceHolderBorder, Path=ActualHeight}"
/>
<StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="2" Margin="5">
<Button Command="{Binding UpdateCommand}" Content="{Binding UpdateButtonLabel}"></Button>
<Button Command="{Binding ResetCommand}" Content="{Binding ResetButtonLabel}"></Button>
<Button Command="{Binding CloseConfirmCommand}" Content="{Binding CloseButtonLabel}"></Button>
</StackPanel>
</Grid>
</ScrollViewer>
I've a shell window constructed of an Header, Main Content and Footer.
The main content is a tab control.
According to the design, one of the tab items content (a user control) needs to expand a little bit over the footer.
At first I thought about implmenting this with a negative Margin, but the footer no matter what I did always get drawn on top of my content.
For example consider the following xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
</Grid.RowDefinitions>
<StackPanel Background="Blue" Grid.Row="0"/> <!-- Header -->
<StackPanel Background="Red" Grid.Row="2"/> <!-- Footer -->
<TabControl Grid.Row="1" > <!-- Content -->
<TabItem>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Background="Yellow" >
<Button Width="100" Height="50" Content="Text" />
</StackPanel>
</Grid>
</TabItem>
</TabControl>
What I would want to achieve is making the Yellow StackPanel to reach the bottom of the screen somewhow, overlapping on top of the red footer.
Hope it is understandable.
Thanks
Ariel
Try this code sample:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.ColumnSpan="3" Background="Blue" Grid.Row="0"/> <!-- Header -->
<StackPanel Grid.ColumnSpan="3" Background="Red" Grid.Row="2"/> <!-- Footer -->
<TabControl Grid.ColumnSpan="3" Grid.Row="1"> <!-- Content -->
<TabItem>
<Grid>
<Button Width="100" Grid.Column="1" Height="50" Content="Text" />
</Grid>
</TabItem>
</TabControl>
<StackPanel Grid.Column="1" Grid.Row="3" Background="Yellow" />
</Grid>
The problem is that you want the stackpanel contained within the tab control, but you want it to extend beyond the bottom of the tab control. This isn't supported by the tab control.
No doubt TabControl is the problem. Maybe try to write your own TabControl.
Cheers.