Please have a look at my code below:
<Border Background="#242328" CornerRadius="10" Opacity="0.9">
<Grid Width="400">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding [someViewModel].Title}" Margin="0,20,0,20"/>
<StackPanel Grid.Row="1" Orientation="Vertical">
<TextBlock Margin="20,0,0,0" Text="{Binding [someViewModel].AnotherText}"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Vertical">
<Image Source="{Binding [someViewModel].source}" Width="100" Height="100"/>
<TextBlock Margin="20,0,0,0" Text="{Binding [someViewModel].AnotherText2}"/>
</StackPanel>
<Grid Grid.Row="3" Width="250" Margin="0,10,10,10">
<Button Width="120" Height="50" Background="#638699" Content="OK" FontSize="18"/>
</Grid>
</Grid>
</Border>
Output of the code above:
Now my question very simple, why there is empty space above the button? I've already set all RowDefinition Height="Auto", when there isn't any value in my variable, shouldn't the box shrink to left only button?
Please note that all the variable such as [someViewModel].Title, [someViewModel].AnotherText, [someViewModel].AnotherText2, [someViewModel].Source will be null
Have a look at your designer and you will see something like this
Your TextBlock and StackPanels will be rendered and it doesn't matter if they have a value or not. If you want to hide them when they don't have a value you can use an IValueConverter to determine their visibilty based on their content.
Some of your controls in the Auto sized rows do have a height > 0 even if they don't display anything. This causes the calculated row height to also be > 0.
For example the Margin on your TextBlock causes a calculated height.
Also the Image control height is set to 100, no matter if you assign a source or not.
Related
I am having a grid which contains six rows(each row is a stack Layout).
Inside my fifth row(i.e 5th stack layout) I am having a grid.I gave 100% width for that grid, but that grid is not occupying 100% of the width.
How do I fix this problem?
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Vertical">
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Vertical">
<Grid Width="100%">
</Grid>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Vertical">
</StackPanel>
</Grid>
I think , you can try removing the stack panel and you can use Grid.Row on Grid and that would fix the issue.
I haven't see percentages used in UWP before and even think it is not a valid syntax. I think you should use HorizontalAlignment="Stretch" instead to stretch the Grid to full width.
#Martin Zikmund and #Durai Amuthan.H's suggestions were all correct. The Width=100% in UWP XAML layout doesn't support.
If you want to make the Grid's has the same width as the StackPanel and automatically resize when the window resized, you could also remove the Width directly like the following:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Vertical">
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Vertical">
<Grid Background="Red">
<TextBlock Text="abc"></TextBlock>
</Grid>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Vertical">
</StackPanel>
</Grid>
Basically what the title says. The stackpanel overlaps the menu and I have no idea why. Here is the XAML.
<Grid>
<Menu x:Name="menu" HorizontalAlignment="Left" Height="25" VerticalAlignment="Top" Width="592"/>
<StackPanel x:Name="LOCATIONS" HorizontalAlignment="Left" Margin="0,25,0,0" VerticalAlignment="Top" Height="294" Width="200" Background="LightGray"/>
</Grid>
</Window>
Program
The reason why is because Grid is a container. If you add elements as children, they are all going to overlap each other with the last child always on top.
What you need to do is use Rows in your Grid so that each child element has its own dedicated area.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu x:Name="menu" Grid.Row="0" Height="25" />
<StackPanel x:Name="LOCATIONS" Grid.Row="1" HorizontalAlignment="Left" Width="200" Background="LightGray"/>
</Grid>
The above code allows you to remove un-necessary Heights and Alignments.
You can use a DockPanel as well to achieve the same effect.
<DockPanel LastChildFill="True">
<Menu x:Name="menu" DockPanel.Dock="Top" Height="25" />
<StackPanel x:Name="LOCATIONS" HorizontalAlignment="Left" Width="200" Background="LightGray"/>
</DockPanel>
You need to define rows or columns for the Grid.
I suggest you read this tutorial:
http://www.wpftutorial.net/gridlayout.html
You are filling your grid with 2 elements at the same time. Instead, you should define two rows in your grid. One row with a height of 20 pixel and the second row filling the rest.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="100*/>
</Grid.RowDefinitions>
<Menu x:Name="menu" Grid.Row="0"/>
<StackPanel x:Name="LOCATIONS" Grid.Row="1" Background="LightGray"/>
</Grid>
This should solve your problem.
In Grid, highest z-index is applied to element which is last applied, so here as you are declaring stackpanel after menu, it is getting z-index of 1 more than Menu which ha bee give z-index of 0, so better you use Grid.Row or Panel.Z-index more..
I've got a XAML page which is broken down with a grid as follows:
<Grid Background="Green">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
The first and third row contain a TextBlock each and are set to auto-resize to their height and the ListView is contained in the middle row and it is suppose to stretch within the area.
The ListView appears to be resized based on the number of items rather than the available visible area that should be allocated to the middle row.
This has 2 side effects:
I can't scroll to view the other items
It pushes the TextBlock in the third row out of the screen.
If I set a specific height on the ListView, it works as expected but I want my ListView to use the entire area of the screen between the top and bottom rows.
It displays as expected in the IDE, but no data is loaded but I can clearly see my top and bottom row (in green) and I can see the ListView is stretched between these 2 rows.
I've used this numerous times in the past but with a universal app for Windows 10, so I'm wondering if this is a new behaviour I'm not aware of or is this a bug?
This is full code without the DataTemplate for clarity sake. Just to be clear, my DataTemplate is displaying correctly, but I just can't scroll as there is no scrollbar since the listview is stretched based on the items, rather than being restricted to the available area of the middle row.
<Grid Background="Green">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Top Row" />
<ListView ItemsSource="{Binding Items}"
Grid.Row="1"
Background="Red">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
....
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Text="bottom row" Grid.Row="2"/>
</Grid>
You need to wrap your ListView in a ScrollView. This will fill the empty area and add a scroll bar as the list overflows the empty area.
I figured out the problem. It isn't a change in behaviour or a bug!
As someone mentioned that they tried to reproduce the problem and couldn't, I decided to do the same.
When I put my grid and ListView directly on the MainPage, I couldn't reproduce it.
When I put my grid and ListView on a sub-page (i.e. GridPage) and loaded it into the frame contained on the MainPage, I couldn't reproduce it
and that's when the penny dropped!!
In my code, I used (for the first time) a SplitView and this SplitView was contained in a grid with 2 rows and stupidly, both rows were set to "Auto" when I should have set the first one to Auto for my hamburger menu, logo and title and the second one should have been set to '*'.
The second I changed my second row to '*', the problem got sorted. It had nothing to do with the Grid Page which contained the grid I originally posted problem with.
<Grid Background="{ThemeResource FocusVisualWhiteStrokeThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
Here is the full code:
<Grid Background="{ThemeResource FocusVisualWhiteStrokeThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Background="White"
Grid.Row="0"
Grid.Column="0"
Margin="0,10,0,10">
<ToggleButton Style="{StaticResource SymbolButton}"
Foreground="{ThemeResource ApplicationForegroundThemeBrush}"
FontSize="{ThemeResource ControlContentThemeFontSize}"
Command="{Binding HamburgerCommand}" >
<FontIcon x:Name="Hamburger"
FontFamily="Segoe MDL2 Assets"
Glyph=""
Foreground="#ff6600" />
</ToggleButton>
</Border>
<Border Background="White" Grid.Row="0"
Grid.Column="1" Margin="10,0,0,0">
<Image Stretch="Fill" Source="{Binding SelectedSection,
Converter={StaticResource SectionImageConverter}}"
Height="20" Width="20" />
</Border>
<Border Background="White"
Grid.Row="0"
Grid.Column="2"
Margin="10,0,0,0">
<TextBlock x:Name="Header" Text="{Binding SelectedSection,
Converter={StaticResource
SectionTitleConverter}}"
Style="{StaticResource TagLineTextStyle}"
Foreground="#ff6600"
VerticalAlignment="Center"
Margin="10,0,0,0"/>
</Border>
</Grid>
<SplitView x:Name="Splitter"
IsPaneOpen="{Binding IsPageOpen}"
DisplayMode="Inline"
Grid.Row="1">
<SplitView.Pane>
<ListBox x:Name="SectionControl" SelectionMode="Single"
ItemsSource="{Binding Sections}"
HorizontalAlignment="Left"
Background="White"
BorderThickness="0"
VerticalAlignment="Top"
SelectedItem="{Binding
SelectedSection, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource
SectionImageConverter}}"
Height="17" Width="17"/>
<TextBlock Text="{Binding
Converter={StaticResource
SectionTitleConverter}}"
Margin="20,0,0,0"
Foreground="#ff6600" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Core:InvokeCommandAction Command="{Binding
ItemClickCommand}"
CommandParameter="{Binding SelectedSection}" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ListBox>
</SplitView.Pane>
<SplitView.Content>
<Frame x:Name="SectionFrame"/>
</SplitView.Content>
</SplitView>
</Grid>
Thanks again for the feedback/help. Much appreciated!
I have image and 3 textblock. I want place image left and 3 TextBlock in rows right. I've tried this:
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.RowSpan="3"
Source="image.jpg" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock Grid.Column="1"
Text="11"
FontSize="25"/>
<TextBlock Grid.Column="1"
Grid.Row="1"
Text="22"/>
<TextBlock Grid.Column="1"
Grid.Row="2"
Text="33" FontSize="14"/>
</Grid>
But I have large space between rows when image is big. How I can do this?
If you want the image to remain its size... simply get rid of the grid rows and throw the TextBlocks into a vertical StackPanel.
If you want to resize your image so that it has the same height as the 3 TextBlocks... you can bind the Height of the Image to the ActualHeight of whatever container you put the TextBlocks in, like this:
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Height="{Binding ActualHeight, ElementName=myStackPanel}" Source="image.jpg" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<StackPanel Grid.Column="1">
<StackPanel Name="myStackPanel">
<TextBlock Text="11" FontSize="25"/>
<TextBlock Text="22"/>
<TextBlock Text="33" FontSize="14"/>
</StackPanel>
</StackPanel>
</Grid>
I would try to make a grid with 1 row and 2 columns.
In the first column i would place the image.
In the second column i would place a stack panel with vertical flow.
Then add the textblocks to the stackpanel.
I am trying to format the scroll view to completely occupy the parent container, but it looks like I'm missing something. Any suggestions would be great.
XAML:
<Border Grid.Row="0" BorderBrush="#1B5468" BorderThickness="3,3,3,3" CornerRadius="7,7,7,7" Margin="5,0,5,5">
<StackPanel Height="Auto" Width="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<StackPanel HorizontalAlignment="Center" Width="350" Height="30">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Image Source="../Images/Blue.png" Stretch="Fill" Margin="7,0,5,-27" Height="52" />
<TextBlock HorizontalAlignment="Center" Height="Auto" Margin="36,3,-2,4" Name="lblHeader" Text="Comments" VerticalAlignment="Center" Width="Auto" Foreground="Silver" FontWeight="Bold" FontSize="12" />
</Grid>
</StackPanel>
<ScrollViewer Height="Auto" HorizontalAlignment="Stretch" Name="dComments_Scroll" VerticalAlignment="Stretch" Width="Auto" HorizontalContentAlignment="Left" VerticalContentAlignment="Top">
<StackPanel Height="Auto" Name="dStack_Comments" Width="Auto" HorizontalAlignment="Left" VerticalAlignment="Top" UseLayoutRounding="False">
</StackPanel>
</ScrollViewer>
</StackPanel>
</Border>
By putting your ScrollViewer in a StackPanel, you're saying "make this ScrollViewer just tall enough to hold its content". That's what StackPanel is designed to do -- to make each child exactly as tall as it needs to be to show all its content, and then stack the next child right underneath. If that's not the layout you want, don't use a StackPanel.
Edit: Instead of a StackPanel inside your Border, you probably want a Grid. (I originally wrote DockPanel, forgetting that Silverlight doesn't ship with a DockPanel.) Grid is flexible enough to let you have some controls autosized, and other controls filling (or sharing) the remainder of the available space.
<Border ...>
<Grid ...>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" ...>
...
</StackPanel>
<ScrollViewer Grid.Row="1" ...>
...
</ScrollViewer>
</Grid>
</Border>
Also, once you get it working, I'd strongly suggest that you see if you can simplify your XAML. You're setting a lot of properties to their default values (e.g. HorizontalAlignment="Stretch", Height="Auto"), which just makes your XAML harder to read and maintain. If you can start to learn which attributes you can remove and still keep the same behavior, you'll have a much better handle on XAML development.