I'm developing a resolution independent application in WPF. I am using mahapps metro controls in my application. I have a grid which is divided into rows and columns in * and 4 TextBoxes are occupying specific rows and columns in that grid.
The problem is that the TextBox is not occupying the row as in the bottom border of
Textbox is not visible but when I change style to x:Null the problem disappears. Is this a problem specific to metro TextBox?. I tried VerticalAlignment = "Stretch" but this does'nt help.
Also the bottom part is visible in higher resolution like 1440 X 900 but not in 1366 X 768. What am I missing?
<Grid Background="Azure">
<Grid.RowDefinitions>
<RowDefinition Height="13.1578*"/>
<RowDefinition Height="4.8157*"/>
<RowDefinition Height="13.1578*"/>
<RowDefinition Height="4.8157*"/>
<RowDefinition Height="13.1578*"/>
<RowDefinition Height="4.8157*"/>
<RowDefinition Height="13.1578*"/>
<RowDefinition Height="4.8157*"/>
<RowDefinition Height="13.1578*"/>
<RowDefinition Height="4.8157*"/>
<RowDefinition Height="18.4210*"/>
<RowDefinition Height="4.8157*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="90*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0"
Grid.RowSpan="12"
Grid.Column="0"
Grid.ColumnSpan="3">
<Border BorderBrush="Black"
BorderThickness="1"/>
</Grid>
<TextBox x:Name="txt_1"
Controls:TextBoxHelper.Watermark="Textbox 1"
Style="{x:Null}"
Grid.Row="2"
Grid.Column="1"/>
<TextBox x:Name="txt_2"
Controls:TextBoxHelper.Watermark="Textbox 2"
Style="{x:Null}"
TextWrapping="Wrap"
Grid.Row="4"
Grid.Column="1"/>
<TextBox x:Name="txt_3"
Controls:TextBoxHelper.Watermark="Textbox 3"
Style="{x:Null}"
TextWrapping="Wrap"
Grid.Row="6"
Grid.Column="1"/>
<TextBox x:Name="txt_4"
Controls:TextBoxHelper.Watermark="Textbox 4"
VerticalAlignment="Stretch"
TextWrapping="Wrap"
Grid.Row="8"
Grid.Column="1"/>
<Grid Grid.Row="10"
Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32.5*"/>
<ColumnDefinition Width="35*"/>
<ColumnDefinition Width="32.5*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn_add"
Content="Add"
Grid.Row="8"
Grid.Column="1"
Click="btn_add_Click"/>
</Grid>
<StackPanel Background="#C0F368"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3">
</Grid>`
I have a DockPanel, which contains some controls including a ScrollViewer.
What I WANT to happen, is for the ScrollViewer to allow the grid to be scrolled, without pushing other controls off the bottom of the form.
Instead, the ScrollViewer expands to the height of the window, rather than the top of the Button, pushing the Button off for the bottom of the form. Why is this? How do I fix it?
<Window x:Class="Class1.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:Class1"
mc:Ignorable="d"
Title="MainWindow" Height="800" Width="600"
WindowStartupLocation="CenterScreen">
<DockPanel LastChildFill="False">
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Name="miQuit" Header="Quit" Click="miQuit_Click" />
</MenuItem>
</Menu>
<ToolBarTray DockPanel.Dock="Top" IsLocked="True">
<ToolBar>
<Button Name="btnQuit" ToolBar.OverflowMode="Never" Click="btnQuit_Click">
Quit
</Button>
</ToolBar>
</ToolBarTray>
<ScrollViewer VerticalScrollBarVisibility="Auto" DockPanel.Dock="Top" VerticalAlignment="Stretch">
<Grid Name="gMainGrid" ScrollViewer.CanContentScroll="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Grid.Column="0" Grid.Row="0" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="1" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="2" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="3" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="4" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="5" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="6" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="7" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="8" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="9" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="10" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="11" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="12" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="13" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="14" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="15" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="16" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="17" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="18" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="19" Width="100" Margin="10,10,10,10"/>
<TextBox Grid.Column="0" Grid.Row="20" Width="100" Margin="10,10,10,10"/>
</Grid>
</ScrollViewer>
<Button Name="btnButton1" DockPanel.Dock="Bottom" Click="btnButton1_Click" >ButtonText</Button>
</DockPanel>
I want the menu bar at the top of the screen, the button at the bottom of the screen, and the grid with the ScrollViewer in the middle. What am I doing wrong?
The problem is that the ScrollViewer doesn't know how much height it should get. ScrollViewer is a control that tries to get as much size as its children need. DockPanel also gives as much size as the ScrollViewer need and therefore your problem. You can fix height of the ScrollViewer with pixels (i.e. Height=100) To make it a fixed height. I don't know your use case so this might be useful if you are showing an image carousel for example.
In more general layout advice I might say that you'd better use a grid instead of a DockPanel:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<!-- Next one is for middle part of the page -->
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<!-- your controls here -->
</Grid>
I found that I could have a dynamic height with the DockPanel if I stuck the whole thing in a Grid. This appears to work, as I can now have a dynamic height for the ScrollViewer.
<Window x:Class="Class1.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:Class1"
mc:Ignorable="d"
Title="MainWindow" Height="800" Width="600"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Grid.Column="0" Grid.Row="0" LastChildFill="False">
Everything is then as normal EXCEPT that I move my button outside of the DockPanel and into the Grid's second row:
</DockPanel>
<Button Grid.Column="0" Grid.Row="1" Name="btnButton1" DockPanel.Dock="Bottom" Click="btnButton1_Click" >ButtonText</Button>
</Grid>
The rows with a Height of "Auto" will size to fit their content. The rows with a Height of asterisk (*) will size to fill the remaining space after the size of the Autos has been calculated. Thus everything sizes up correctly and nicely.
Alternatively, at this point I can do-away with the DockPanel entirely and have the Menu, ToolBarTray, ScrollViewer, and Button in their own separate grid rows, like Emad suggests in their answer (although I'm not sure what the extra row is for in their example).
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
I ultimately decided to go for that approach, so I'll mark it as the answer, but I'm putting this all here for the full explanation, for completeness (in case people do happen to want to keep their DockPanel).
I have a Grid with 2 rows and in the first row 2 columns each with 2 rows.
The GridSplitter is inside the 2nd column. I do not know why the it does not move. I am thankfull for any help. ( I'm new here :-) )
With regards
Below XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="yyy:" Margin="10" MinWidth="50"/>
</StackPanel>
</StackPanel>
<TreeView Grid.Row="1" x:Name="TreeView0"></TreeView>
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10" Text="xxx:" HorizontalAlignment="Left" MinWidth="140"/>
</StackPanel>
</StackPanel>
<TreeView Grid.Row="1" x:Name="TreeView1"></TreeView>
<GridSplitter Grid.Row="1" Width="2" Background="Gray" HorizontalAlignment="Left" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext"/>
</Grid>
</Grid>
<Grid Grid.Row="1">
<ListView Margin="10">
<ListView.View>
<GridView></GridView>
</ListView.View>
</ListView>
</Grid>
</Grid>
After rearranging some rows and cloumns, I could solve my problem.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="x:" Margin="10" HorizontalAlignment="Left" MinWidth="50"/>
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10" Text="y:" HorizontalAlignment="Left" MinWidth="140"/>
</StackPanel>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<TreeView x:Name="TreeView0"></TreeView>
</Grid>
<GridSplitter Grid.Column="1" Width="2" Background="Red" HorizontalAlignment="Center"/>
<Grid Grid.Column="2">
<TreeView x:Name="TreeView1"></TreeView>
</Grid>
</Grid>
<Grid Grid.Row="2">
<ListView Margin="10">
<ListView.View>
<GridView></GridView>
</ListView.View>
</ListView>
</Grid>
</Grid>
#Frisbee I am not ashamed to refer at MSDN or somewhere else. I came here in search of help. I did not ask you to fix my problem. Your approach of helping someone is realy disgusting and boaring. Instead of responding with rubbish words you could have concentrated on the issue.
You have the splitter in a row height *
Wrong
The splitter needs to be in an auto with height * above and below
I have a page , here is the XAML . Think that the window has a TabControl , I create a tab -> frame -> page. The problem is that the two last DataGrids height is more that the page height! Any help appresiated! thanks.
<Page x:Class="pObjectDesigner"
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:STUDIO_MANAGER_FRAMEWORK"
mc:Ignorable="d" x:Name="pObjectDesigner"
d:DesignHeight="750" d:DesignWidth="1050" MinWidth="500"
Title="pObjectDesigner">
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<local:ucMXMainToolBar Grid.Row="0" Allow_GoLeft="False" Allow_GoRight="False" x:Name="tlbToolBar" VerticalAlignment="Top" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" MinWidth="180"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TreeView x:Name="tlstObjects"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" x:Name="grdPages"
AutoGenerateColumns="True"
ColumnWidth="Auto"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
CanUserReorderColumns="True" />
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch"/>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions >
<ColumnDefinition Width="0.5*" MinWidth="150" />
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="0.5*" MinWidth="150"/>
</Grid.ColumnDefinitions>
<DataGrid Grid.Column="0" x:Name="grdDataGrids"
AutoGenerateColumns="True"
ColumnWidth="Auto"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
CanUserReorderColumns="True"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<DataGrid Grid.Column="2" x:Name="grdModules"
AutoGenerateColumns="True"
ColumnWidth="Auto"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
CanUserReorderColumns="True"/>
</Grid>
</Grid>
</Grid>
</Grid>
</Page>
Hi in DataGrid use AttachedProperty ScrollViewer.VerticalScrollBarVisibility to Auto
<DataGrid **ScrollViewer.VerticalScrollBarVisibility="Auto"**
Similarlly you can set it for Horizontally .I hope this will help.
Here's my code (which isn't working btw):
<DockPanel MinWidth="776" Margin="13" LastChildFill="True" Height="522" VerticalAlignment="Top">
<Grid DockPanel.Dock="Top" MinWidth="200">
<Grid.RowDefinitions>
<RowDefinition Height="70" />
<RowDefinition Height="*"/>
<RowDefinition Height="150" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
...
</DockPanel>
When I vertically size the control everything just sticks to the top (which I want, except for the middle to stretch).
Thanks in advance!
If you can just stick to dock panels, you do something like the following:
<DockPanel LastChildFill="true">
<DockPanel DockPanel.Dock="Top" Height="70" />
<DockPanel DockPanel.Dock="Bottom" Height="150" />
<DockPanel DockPanel.Dock="Top"><!-- Expandable content here--></DockPanel>
</DockPanel>
You will have to remove some values from the dock panel LastChildFill="True", Height="522" VerticalAlignment="Top" are stopping the grid from sizing.
Try this:
<DockPanel MinWidth="776" >
<Grid DockPanel.Dock="Top" MinWidth="200">
<Grid.RowDefinitions>
<RowDefinition Height="70" />
<RowDefinition Height="*"/>
<RowDefinition Height="150" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Fill="Blue" Grid.Row="0" />
<Rectangle Fill="Green" Grid.Row="1" />
<Rectangle Fill="Red" Grid.Row="2" />
</Grid>
</DockPanel>