Formatting ScrollView to occupy the parent container - c#

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.

Related

WPF Stackpanel overlaps other elements

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..

How to make xaml Page the full width of screen

I have the following MainPage.xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel>
<Button Name="btnHamburger" FontFamily="Segoe MDL2 Assets" Content="" Click="HamburgerButton_Click" RelativePanel.AlignLeftWithPanel="True"/>
<TextBlock Name="PageTitle" Text="Title" FontSize="24" FontWeight="Bold" RelativePanel.AlignHorizontalCenterWithPanel="True"/>
</RelativePanel>
<SplitView Name="MySplitView" Grid.Row="1" DisplayMode="Overlay" OpenPaneLength="170" CompactPaneLength="56" HorizontalAlignment="Left">
<SplitView.Pane>
<StackPanel Orientation="Vertical">
<TextBlock Text="Skyron Image" FontSize="16" VerticalAlignment="Center" />
<ListBox SelectionMode="Single" Name="IconsListBox" SelectionChanged="IconsListBox_SelectionChanged">
</ListBox>
</StackPanel>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame" />
</SplitView.Content>
</SplitView>
</Grid>
It gives me a navigation menu system. When I click on of the navigation links, I load the corresponding page into the Frame MyFrame.
This is my HomePage
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Home page" Name="tbHome" />
</Grid>
As you can see, I've tried to achieve my desired outcome by setting HorizontalAlignment="Stretch" on the grid and setting a column definition to auto.
I guess the issue is that I don't have enough content in the grid to make it full screen. This is what I currently have:
I have made the homepage background blue - as you can see, it doesn't fill the entire screen.
How can I achieve what I want, without setting a width on the Grid - as this won't work with different sized phones/screens.
EDIT:
I've just relised the width of the content is being controlled by the OpenPaneLength="170" setting. Why does this effect the content and how can I stop it effecting the content width?
Set the HorizontalAlignment property of the SplitView to "Stretch" instead of "Left".

Listview is resizing correctly in Universal App Windows 10

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!

WPF - Canvas Background Not Displaying

I am a complete newbie to WPF. I've been working on a personal project for about 2 weeks. It's been coming along, and suddenly hit a roadblock. Everything was working perfect until I shifted some things around.
It's basically a satellite map as the canvas background, so that I can overlay geometry on it. The image is 10000x10000, and has not changed. It's added as a resource and... funny enough, shows up in the Visual Basic xaml designer.
The local:ZoomBorder class zooms/pans the viewbox/canvas. I did not post the code because it has not been touched since it last worked.
Geometry is being added to the canvas correctly.
I moved around some dimensions, as far as the grid goes. Like adding margins and such, but can't get it back to displaying the imagebrush background, no matter what I do.
<Window x:Class="Temp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Temp"
Title="MainWindow" Height="930" Width="1100" PreviewKeyDown="mapBorder_PreviewKeyDown">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="210" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="2" Grid.Column="0">
<StackPanel Name="stackPanel" />
</ScrollViewer>
<local:ZoomBorder x:Name="mapBorder" Background="Gray" Margin="0" Grid.Column="1" Grid.Row="2" ClipToBounds="True">
<Viewbox>
<Canvas Name="mapGrid" Height="10000" Width="10000">
<Canvas.Background>
<ImageBrush ImageSource="map.jpg"/>
</Canvas.Background>
</Canvas>
</Viewbox>
</local:ZoomBorder>
<Button Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" MinWidth="80" Margin="10,0,0,0" Content="Start Refresh" Width="80" Click="buttonStartRefresh" />
<Button Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" MinWidth="80" Margin="110,0,0,0" Content="Stop Refresh" Width="80" Click="buttonStopRefresh" />
<CheckBox Name="Advanced" Grid.Column="1" Grid.Row="1" Margin="10,0,0,0">
<Label Margin="0,-5,0,0">Advanced</Label>
</CheckBox>
</Grid>
</Window>

RowDefinition Height = Auto doesn't work?

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.

Categories

Resources