I have a Xaml view where I'm trying to display Textbox inside a grid which is inside an Exander.
<Expander DataContext="{Binding DiagnosticCategories[0].DiagnosticResults[0]}" <!-- For the test -->
Background="Transparent"
Foreground="{StaticResource ActiveForegroundBrush}"
IsExpanded="False">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="A" />
<ColumnDefinition Width="*" SharedSizeGroup="A" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Top">
<TextBox
Margin="10"
Background="Transparent"
BorderThickness="0"
FontSize="13"
FontWeight="Light"
Foreground="{StaticResource ActiveForegroundBrush}"
IsReadOnly="True"
Opacity="0.8"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionBrush="Black"
Text="{Binding FormatedParameters, Mode=OneWay}"
TextWrapping="Wrap" />
</StackPanel>
[...]
</Grid>
</Expander>
However, there is a problem with the Textbox which has a anormal height even if my text is just "aa"...
First, I thought that the problem was with the Grid.Row and the Textbox only fit it so I tried to add a StackPanel which doesn't fit the Grid.Row but it doesn't work. It seems that the problem is in the textbox.
With a TextBlock, I don't have this problem but I need the Textbox to display my text.
You can try RichTextBox.
When I want to use TextBox, I have the same problem under a certain height. I solved the problem by using RichTextBox instead of TextBox.
<Expander DataContext="{Binding DiagnosticCategories[0].DiagnosticResults[0]}" <!-- For the test -->
Background="Transparent"
Foreground="{StaticResource ActiveForegroundBrush}"
IsExpanded="False">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="A" />
<ColumnDefinition Width="*" SharedSizeGroup="A" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Top">
<RichTextBox
Margin="10"
Background="Transparent"
BorderThickness="0"
FontSize="13"
FontWeight="Light"
Foreground="{StaticResource ActiveForegroundBrush}"
IsReadOnly="True"
Opacity="0.8"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionBrush="Black"
Text="{Binding FormatedParameters, Mode=OneWay}"
TextWrapping="Wrap" />
</StackPanel>
[...]
</Grid>
</Expander>
As others mentioned, I'm a little unsure what you are trying to achieve. I added a couple of horizontal and vertical layouts to your example:
<Expander DataContext="{Binding DiagnosticCategories[0].DiagnosticResults[0]}"
Background="Yellow" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="200"
IsExpanded="False">
<Grid Margin="10" Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="A" />
<ColumnDefinition Width="*" SharedSizeGroup="A" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Top">
<TextBox
Margin="10"
Background="Orange"
BorderThickness="0"
FontSize="13"
FontWeight="Light"
IsReadOnly="True"
Opacity="0.8"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionBrush="Black"
Text="Test Text"
TextWrapping="Wrap"
/>
</StackPanel>
</Grid>
</Expander>
And I get the following:
Closed:
Open:
I have a couple Grid's in my application and the memory usage goes from 70MB up to 300MB when I continuously resize the window (as in making it smaller, bigger, repeat).
There are no bindings or events in my application and I have already removed any Auto layout option I had for rows/columns.
Is this just normal because I have so many Grid's or is there something wrong with my layout?
Video: https://i.gyazo.com/e6292fa9b4e065bf1842c69cbd43b853.mp4
<Window x:Class="CanvasDrawTest.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:CanvasDrawTest"
mc:Ignorable="d"
Title="MainWindow"
Height="863"
Width="1443"
WindowStyle="SingleBorderWindow"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<!-- TopGrid -->
<RowDefinition />
<!-- MainGrid -->
<RowDefinition Height="30" />
<!-- FooterGrid -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Name="TopGrid" Grid.Row="0" Grid.Column="0">
<Menu>
<MenuItem Header="File">
<MenuItem Name="NewDiagramMenuItem" Header="New Diagram" Click="NewDiagramMenuItem_Click" />
</MenuItem>
</Menu>
</Grid>
<DockPanel LastChildFill="True" Grid.Row="1" Grid.Column="0">
<Grid Name="MainGrid" DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75*"/>
<ColumnDefinition Width="643*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,0.333">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" BorderBrush="Gray" BorderThickness="0,0,0.4,0">
<Grid Name="LeftGrid" />
</Border>
<Grid Name="CenterGrid" Grid.Row="0" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="150" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Name="ContentGrid" Grid.Row="0" Grid.Column="1">
<TabControl Name="DocumentTabs" BorderThickness="0" />
</Grid>
<Border Grid.Row="1" Grid.Column="1" BorderBrush="Gray" BorderThickness="0,0.4,0,0">
<Grid Name="BottomGrid" />
</Border>
</Grid>
</Grid>
</Grid>
</DockPanel>
<Grid Name="FooterGrid" Grid.Row="2" Grid.Column="0">
<StatusBar Name="StatusBar" Height="30" />
</Grid>
</Grid>
</Window>
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 an application (implemenented in WPF, XAML) which has 6 rows and 6 columns. At the position Grid.Row="1" Grid.RowSpan="4" Grid.Column="0" Grid.ColumnSpan="5" , I'm using a TabControl for Dashboard, Housekeeping, and Science. In every TabControl, I'm using a ListBox on the left side to choose individual data. The rest (w/o the ListBox) of the field/grid (which should have a size of 4 rows and 4 columns) is available for charts.
Problem
The charts which are visible in the screenshot below should be stretched over 4 rows down to the bottom edge of the application according to the XAML code. The TabControl is not 4 rows as visible because of the white boarder I have attached.
How can I change my grid-concept that it works as described above? Is a grid in the grid, resp. in the TabControl necessary at all?
Screenshot of the WPF application
MainWindow.xaml
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<!-- Definition of Rows and Columns -->
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="250" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="250" />
</Grid.ColumnDefinitions>
<!-- Header -->
<StackPanel Grid.Row="0" Grid.ColumnSpan="6">
<TextBlock Text="RFM DATA ANALYZER" Margin="20" HorizontalAlignment="Center" FontSize="36" FontWeight="Thin" />
</StackPanel>
<!-- Tabs -->
<StackPanel Grid.Row="1" Grid.RowSpan="4" Grid.Column="0" Grid.ColumnSpan="5">
<TabControl TabStripPlacement="Top">
<TabItem Header="Dashboard">
<Border BorderBrush="White" BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.RowSpan="4" Grid.Column="0" Grid.ColumnSpan="1">
<TextBlock Text="Data" Margin="0 50 0 20" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold" FontSize="15" Foreground="LightGray" />
<ListBox >
<ListBoxItem Content="Data 00" />
<ListBoxItem Content="Data 01" />
<ListBoxItem Content="Data 03" />
</ListBox>
</StackPanel>
<oxy:PlotView Model="{Binding Model1}" Background="Transparent" Grid.Row="0" Grid.RowSpan="4" Grid.Column="1" Grid.ColumnSpan="1" />
<oxy:PlotView Model="{Binding Model2}" Background="Transparent" Grid.Row="0" Grid.RowSpan="4" Grid.Column="2" Grid.ColumnSpan="1" />
<oxy:PlotView Model="{Binding Model3}" Background="Transparent" Grid.Row="0" Grid.RowSpan="4" Grid.Column="3" Grid.ColumnSpan="1" />
<oxy:PlotView Model="{Binding Model4}" Background="Transparent" Grid.Row="0" Grid.RowSpan="4" Grid.Column="4" Grid.ColumnSpan="1" />
</Grid>
</Border>
</TabItem>
<TabItem Header="Housekeeping" Height="40">
<Border BorderBrush="White" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
etc.
Replace your StackPanels with Grids. StackPanels size to their child elements, whereas Grids size to their parent.
<StackPanel Grid.Row="1" Grid.RowSpan="4" Grid.Column="0" Grid.ColumnSpan="5">
<TabControl TabStripPlacement="Top">
...becomes...
<Grid Grid.Row="1" Grid.RowSpan="4" Grid.Column="0" Grid.ColumnSpan="5">
<TabControl TabStripPlacement="Top">
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>