How to add multiple controls to PivotItem without messing up vertical scrolling? - xaml

I have a Pivot control in my Windows Phone Mango application and one the pivot items has a listbox. It works perfectly when I have only a ListBox as content of the PivotItem.
<controls:PivotItem Header="Item1">
<ListBox
x:Name="longListBox"
ItemsSource="{Binding AllItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource ItemTemplate}" />
</controls:PivotItem>
Now I would like to add more controls above the list in the PivotItem, say an Image.
<controls:PivotItem Header="Item1">
<StackPanel>
<Image
Source="/Images/header.png"
Height="48"
Width="48"/>
<ListBox
x:Name="longListBox"
ItemsSource="{Binding AllItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource ItemTemplate}" />
</StackPanel>
</controls:PivotItem>
However, with these changes PivotItem vertical scrolling works very strangely, moving listbox items downwards instead of upwards. Essentially, items on the bottom of the ListBox are not accessible.
I've tried setting StackPanel height to some huge number, tried adding ScrollViewer, but can't get it to work.
How can I fix the scrolling problem?

StackPanel gives its children whatever height/width they ask for, and that makes the inner ListBox miscalculates its actual height and then its ScrollViewer won't work properly.
Try changing the StackPanel to a Grid with two rows and it should work.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>

Related

The ScrollViewer automatically changes its height and does not scroll

In my program, I use ScrollViewer to display elements inside, but the problem is that when the ScrollViewer is filled with content, its height automatically changes and it becomes impossible to scroll since the height is equivalent to the content. I put a ScrollViewer inside a Grid and it automatically stretches to its full height VerticalAlignment="Stretch". I can't pre-limit its height because its height automatically adjusts to its parent to fill all the space. How can I solve this?
<Grid Grid.Column="0" RowSpacing="10">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="35"/>
<RowDefinition MaxHeight="35"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="2">
<ScrollViewer VerticalAlignment="Stretch" VerticalScrollMode="Enabled" VerticalScrollBarVisibility="Visible" HorizontalScrollMode="Disabled">
<ItemsControl x:Name="notesContent" Loaded="NotesContent_Loaded" Margin="0,0,15,0">
<ItemsControl.ItemContainerTransitions>
<TransitionCollection>
<AddDeleteThemeTransition>
</AddDeleteThemeTransition>
</TransitionCollection>
</ItemsControl.ItemContainerTransitions>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
The ScrollViewer automatically changes its height and does not scroll
The ScrollViewer parent is Grid, and you have set it's VerticalAlignment proeprty as Stretch, it will vertically fill into grid. And it is by design, you can refer to Grid document.
And if you want to make ScrollViewer scrollable, you need to make the content large than ScrollViewer actual height, and the better way is specific height value for ScrollViewer.

Scrolling Listview inside a grid - UWP

I want to show a listview and an image on a uwp page.Items to listview are adding dynamically. When loading page user can see the full listview. and if he clicks any of it's row the list view will filter based on that clicked row.Then user can see filtered listview and an image below the listview. If the user clicks on image it will again show the full listview without image. Now my issue is I want to display listview with scroll view(scrolling should work when listview height reaches end of screen). and if the user clicks on any row of listview,the height of image should fill from end of filtered listview to bottom of screen.
I have done like below.
<Grid HorizontalAlignment="Stretch" >
<Grid.RowDefinitions >
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView x:Name="ItemListView" Margin="0,0,0,0" ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="Auto" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid >
//binding items here
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Border Background="Green" Grid.Row="1" x:Name="Bg" Tapped="Bg_TappedAsync" Visibility="Collapsed">
<TextBlock x:Uid="txt_string1" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="DetectFromContent" FontSize="15" MaxLines="4" FontFamily="Calibri" FontStyle="Italic"/>
</Border>
</Grid>
When I did like above both list view and image(in code it is a Border) takes half half portion of screen.So when showing filtered listview (it may have only one row) a gap is occurring between listview and image. I want to fill the image with remaining height of screen. How can I achieve it? I don't want to set MaxHeight of listview. Because it should run on various size of devices
When you create two rows with a * for RowDefinition.Height, you will get two equally sized Grid rows, which is the behavior you are seeing. A star gives the row all space that is left after evaluating all rows with Auto and hardcoded pixel height. When there are multiple rows with a star, they will divide the remaining space equally. You can also use values like 2* to say that the row should have twice the height of a * row, so you can create "fractions" like 2:1.
In your case however, you might want to rather use Auto for the second row's Height. Auto will give the row the size it actually needs, so when the image is not displayed, it will effectively have zero height. When the image is displayed, it will be as high as the image and the list will take up the rest of the Grid height thanks to the *.

Panorama-like XAML layout with state and transitions

In my app I'd like to have a page layout as shown on this picture:
It has two content blocks (depicted as plain and shaded rectangles) and two states. In normal (1st) state plain block takes all the screen and is fully visible while shaded is hidden behind screen. In 2nd state shaded block is fully visible and also a small part of plain block is on screen, the rest of it is hidden.
I'd also like to have a nice transition from one state to another. I understand I'd probably need to use ViewStates for this. What I don't understand it what XAML control should I use to represent content blocks. So this is the question: what XAML controls would allow me to express this layout as elegantly and concisely as possible?
How about a grid with 2 rows. A pivot control with your 2 states in each pivot item in first row and your fixed content in second row.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Background="Red">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<phone:Pivot Margin="0,-24,0,0">
<phone:PivotItem Background="Blue">
<StackPanel>
<TextBlock Text="Transition content 1" />
</StackPanel>
</phone:PivotItem>
<phone:PivotItem Background="Brown">
<StackPanel>
<TextBlock Text="Transition content 2" />
</StackPanel>
</phone:PivotItem>
</phone:Pivot>
<StackPanel Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Fixed content" />
</StackPanel>
</Grid>
Swiping on the top box will animate as the standard pivot animation.
If you don't want the user to be able to flick and rather control the two states programmatically then you can simply add IsHitTestVisible="False" on the root pivot control then set the SelectedIndex on the pivot to switch between states.

ItemsControl contents overflow the grid row before getting clipped

I have a page with a two row grid. In the first row I have a databound ItemsControl and in the second row a simple textbox.
The problem is that while the page is loading (i.e. it is animated into the view), the ItemScontrol's content overflows over the entire grid. Only after the page is fully shown after a short while (it seems exactly 1 second, although I haven't measured it), the contents get properly clipped to the Grid row.
Here's what happens while loading the page (not that there are some transitions on this screenshot however they do not have an effect on this behavior):
After the page is fully loaded, contents get clipped properly:
Here's the pseudo-XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ItemsControl ItemsSource="{Binding}">
<!-- grid for each row -->
</ItemsControl>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBox />
</StackPanel>
</Grid>
I figured out that clipping works properly if I set the ItemsControl's (but not the StackPanel's!) height to a fixed value, however of course I don't want the height to be fixed.
Any ideas?

How to set a RichTextBox in Silverlight 4 to fit it's parent height and maintain it on resize?

I am having hard times figuring this out. Here is what I need:
<StackPanel x:Name="container" VerticalAlignment="Stretch">
<RichTextBox Height="???" />
</StackPanel>
Basically what I know I can do is to bind RichTextBox Height to it's parent's height ( Height="{Binding ElementName=container, Path=ActualHeight}". Unfortunately this only works on load, because as it seems ActualHeight and ActualWidth don't notify for changes.
So what is the best way in Silverlight 4 to tell RichTextBox or TextBlock, it doesn't matter, to fill it's parent height, and maintain scrollbar if it's content height is bigger. Is the only way to bind some Resize events and maintain the height explicitly? That seems really ugly to me? Have anybody had this problem as well?
Any resources or information is highly appreciated! Thanks.
Ivan,
The best way to solve this is to use a Grid as the parent for the RickTextBox, instead of a StackPanel. By default, a Grid will "Strectch" its content to take up all of the available space. A StackPanel will only Stretch its content in one diminsion.
As an example, paste the following XAML into my XamlViewer to see the difference:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<RichTextBox
Foreground="Blue" FontSize="24" Background="Yellow">
<Paragraph>RichTextBox inside a StackPanel</Paragraph>
</RichTextBox>
</StackPanel>
<Grid Grid.Row="1">
<RichTextBox
Foreground="Blue" FontSize="24" Background="Tan">
<Paragraph>RichTextBox inside a Grid</Paragraph>
</RichTextBox>
</Grid>
</Grid>
</UserControl>
Good luck,
Jim McCurdy, Face to Face Software and YinYangMoney