ScrollViewer scrolls back when released - silverlight

When I tap and hold and move my list around, it moves, but when I no longer hold, it smoothly scrolls back to beginning of the list. How do I prevent it?
I also tried putting whole ItemsControl inside ScrollViewer - same behavior.
Without ScrollViewer ItemsControl doesn't scroll at all.
I set breakpoints to ManipulationCompleted of ItemsPresenter, ItemsControl and ScrollViewer - in all of them scroll appears in correct position where I left it, but afterwards somewhere it scrolls back.
Here's my xaml markup:
<Grid x:Name="LayoutRoot">
<ItemsControl Name="lbDeployments"
ItemsSource="{Binding Path=Deployments}"
ItemTemplate="{StaticResource DeploymentItem}" >
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Grid>
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</Grid>
Please help

The issue is that the ScrollViewer needs a container of a fixed size to know much it can actually scroll.
You'll need to set the height of the ScrollViewer or the grid that contains it for scrollign to work properly.
Without doing this the scrollviewer thinks it can take as much space as it likes. When this is the case it doesn't need to scroll and what you see when manipulating the content directly isn't actually scrolling but just moving the content wihtin the scrollable area.

Try adding RowDefinitions:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid>
...
</Grid>

Related

Force expander to take all available space

I got something like:
1) <grid> with some rows -> 2) <stackPanel> -> 3) Expander -> 4) Expander content...
..and I can't force expander content to be stretched as long and as wide as possible by currently free space in the given grid.row (#1). Whatever I try, expander keeps using to take minimum necessary space to renders its content. But if I do something like MinHeight=500, then it's OK.
P.S. I had an idea to hack it. Just to create transparent line, stretched through the row, and then bind expander height to the actual height.. but it seems ugly to me. Maybe someone knows another way?
<Grid Name="GlobalPanel" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="0.7*" />
<RowDefinition Height="0.3*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical">
<Expander Name="MainExpander"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<!-- HERE EXPANDERS CONTENT WHICH I WANT TO BE STRETCHED -->
</Expander>
</StackPanel>
</Grid>

WP7: ScrollViewer viewport size

Windows Phone 7. I have a ScrollViewer inside a StackPanel inside a PivotItem inside a Pivot. Above the ScrollViewer, there are some other controls. My intention is that the ScrollViewer takes the available lower part of the screen (~400px), and its content is scrolled vertically (content height ~800px).
Now, right now there's no vertical scrolling - when I try to drag, the view returns in the previous position, as if the viewport size exactly matches the content size. When I look at the ViewportHeight property, it's ~800px - same as content.
Height of the ScrollViewer is not set ("Auto"); I was assuming it would take exactly the available space. That's obviously not the case. Question - short of setting Height by hand, is there a way to implement the logic of "viewport height is exactly how much vertical space you've got left"?
EDIT: here's the XAML, irrelevant details removed:
<Pivot x:Name="Root">
<ctls:PivotItem>
<ctls:PivotItem.Header>Title</ctls:PivotItem.Header>
<StackPanel>
<!-- More stuff here-->
<ScrollViewer Name="MenuPanel" HorizontalScrollBarVisibility="Disabled">
<Canvas x:Name="Menu" HorizontalAlignment="Left" VerticalAlignment="Top">
</Canvas>
</ScrollViewer>
</StackPanel>
</ctls:PivotItem>
</Pivot>
Width and height of the canvas are set in code.
Two things:
A StackPanel doesn't allow it's children to automatically take up the rest of the space available. Use a Grid, instead, with defined Rows. This allows your ScrollViewer to be in a container which is the exact height remaining vertically.
Your Canvas (inside the ScrollViewer) is aligned to top and left, and without a size defined, is exactly 0 pixels high and 0 pixels wide.
Good luck.
<Pivot x:Name="Root">
<ctls:PivotItem>
<ctls:PivotItem.Header>Title</ctls:PivotItem.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<!-- More stuff here-->
</Grid>
<ScrollViewer
Grid.Row="1"
Name="MenuPanel">
<Canvas x:Name="Menu"
Height="500"
Width="500"/>
</ScrollViewer>
</StackPanel>
</ctls:PivotItem>
</Pivot>
Without seeing your XAML this is assummed - but based on commonly seen issues
The ScrollViewer is actually being assigned all the space it needs to include all it's content items.
Either give it an absolute height or wrap it in a Grid, which will limit it to the available space within the StackPanel.

Silverlight 4 - ScrollViewer and child DataGrid MinHeight

edit: I'm rewriting almost the entire question because I realized the question was incorrect and confusing. I apologize for this, but the question had incorrect assumptions that made it impossible to answer. I originally tried to simplify it to make it easier to understand, but this made it impossible to replicate my problem.
If I have an DataGrid with a MinHeight in a ScrollViewer, I would expect that as my ViewPort shrinks, the ActualHeight of the element would be decreased until it hits MinHeight before the scrollbars show up.
Instead, it seems that when the datagrid's rows cumulative heights add up to more than the MinHeight, this value overrides MinHeight
Is there a way to do this without manually sizing everything and having a ton of code?
Example:
<ScrollViewer VerticalScrollBarVisibility="Auto" Background="Red">
<Grid x:Name="LayoutRoot" Background="Black" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition MinHeight="20"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<sdk:DataGrid AutoGenerateColumns="True" Name="dataGrid1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MinHeight="20" />
<Rectangle Fill="Blue" Width="100" Height="80" Grid.Row="1" />
</Grid>
</ScrollViewer>
If you were to populate this grid with some rows, if you maximize the window, the grid takes up most of the space and has white space after the rows. If you shrink it down, the layout takes away from the white space until that space runs out, then the root level ScrollViewer kicks in, even though MinHeight has not been reached.
If you replace the DataGrid with another rectangle, the behavior is different (obviously). The new rectangle would shrink down to height 20.
How do I achieve this with the grid? My requirements are to have nested scrollbars on my SL page (which I find distasteful, but it's not in my control). The idea is that the top level scrollbars are a "last resort" of sorts.
What about this:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="250" />
</Grid.RowDefinitions>
<Rectangle MinHeight="150" Background="Red" Grid.Row="0" />
<Rectangle Height="250" Background="Blue" Grid.Row="1" />
</Grid>
You did not have the Grid.Row values set on either of the rectangles.
You've not provided sufficient information to solve your specific problem. However, it is easy to demonstrate that the ScrollViewer does work in exactly the fashion you desire by distilling down to something as simple as:
<UserControl ...>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Border MinHeight="200" BorderBrush="Blue" BorderThickness="1" Background="Red"/>
</ScrollViewer>
</UserControl>
Put this in a standalone Silverlight application in the main page and you'll see that the ScrollViewer only displays the vertical scroll bar when the window is small enough. You can download the solution here.
This is because ScrollViewer itself has a border and padding that occupies little space of its own. Try considering little extra height that should match space of scrollbar border.
Another option will be to change the control template of scrollviewer and remove the border and extra space occupied around content presenter. And set horizontal scroll visibility to collapsed so it will not occupy space.

WPF , Getting verticalstretch working as expected!

I am trying to make the vertical stretch to work as expected i WPF, but for some reason it only takes the space it needs, and not the space available.
First, I am using WPF with C#, and Prism.
In the Shell.xaml (main xaml for the application) I have a grid with 2 columns and one row. The idea is to have a side panel and a main app area. The main app area grid is set to Auto Width and Auto Height. This is working as expected, and it does scale to fit the whole application in Height and Width.
Then I am using prism to insert the view (as a UserControl component) into the main app area. The UserControl is also set to Auto Width and Height, and by looking at the default settings in Expression Blend, the HorizontalAlignment and the VerticalAlignment are set to stretch!
However, the prism loaded UserControl only stretches in Width and not in height! By giving this a background color for visual feedback, I can see that it only takes the vertical space as needed, and not the whole area available!
What could be the solution for this? I have tried going trough all settings an manually overriding them to Width and Height Auto, Horizontal and Vertical Alignment to Stretch, but nothing seems to work as expected!
Some code:
(Shell.xaml)
<Window Height="1140" Width="1450">
<Grid Margin="0" Background="White">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="#FFEEEEEE" Grid.Column="0" Grid.Row="0">
</Grid>
<ItemsControl Width="Auto" Height="Auto" Grid.Row="0" Grid.Column="1" Name="MainRegion" cal:RegionManager.RegionName="MainRegion" Padding="10" Margin="10, 0, 0, 0" Background="#FFFFFFD5" />
</Grid>
</Grid>
</Window>
(view that should inherit the parent height):
<UserControl Width="Auto" Height="Auto" Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- I want this to take the full width and height of the parent -->
</UserControl>
So is this a limitaion in the way the views are loaded into the main xaml, or is this a UserControl limitation, or something else that I do not understand?
Just to clarify; I do see the background color of ItemsControl defined in Shell.xaml stretching both Horizontal and Vertical, but not the background of the view loaded into ItemsControl.
Note that I have removed some of the xaml to make the point easier to understand!
Thanks!
The default for ItemsControl.ItemsPanelTemplate is StackPanel, which compresses all of its children vertically giving the symptoms you describe.
The solution code-zoop gave changes this to <Grid>. This will work well as long as there is can only be one view in the region. But if the region has more than one view they will all be laid on top of each other instead of beside each other.
If you want a region that can handle multiple views but allow views to stretch to the full size of the region, use a DockPanel instead:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
This will put the first view in a panel on the left side, the next one beside it, and so on until the last view which will fill all the remaining space.
If you prefer to have the multiple views stack vertically like they did with StackPanel, you'll have to set that up in ItemContainerStyle:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="DockPanel.Dock" Value="Top" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
I found a solution. I have to override the ItemsPanel Template to use a grid (or similar container):
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I have also in this case removed some of the xaml to make it more readble!
Thanks
Have you tried setting HorizontalContentAlignment and VerticalContentAlignment to Stretch in the ItemsControl?

WPF <StatusBar> is not positioned at the bottom of the window

We have a WPF executable that creates a and then dynamically loads several assemblies. Each assembly represents a screen (.xaml) that is displayed in one of the tabs. The Problem is that the is right under the and not at the bottom of the window. How do I force the to always be at the bottom of the
window? Thx!
UserControl
DockPanel
CheckBox
StatusBar
DockPanel
UserControl
In addition to ArsenMkrt's answer about including the DockPanel.Dock="Bottom" attribute, don't forget that the LAST element in a DockPanel will fill the area unless you explicitly tell it otherwise using a height command (regardless of the DockPanel.Dock attribute provided).
my suggestion is to do thus:
<UserControl>
<DockPanel>
<StatusBar DockPanel.Dock="Bottom" />
<CheckBox />
</DockPanel>
</Usercontrol>
I had the same problem just now. Thanks to Stephen Wrighton's tip that the last element added to a DockPanel fills the area left over, I figured out how to set up my Window. It was a bit weird since I added the Grid last but it was positioned in the middle.
<Window>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
</MenuItem>
</Menu>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem Content="Filler" />
</StatusBar>
<Grid x:Name="rootGrid">
</Grid>
</DockPanel>
</Window>
Did you try?
<StatusBar DockPanel.Dock="Bottom" ... />
In my case adding DockPanel.Dock="Bottom" was not enough I was forced to add VerticalAlignment="Bottom" as well.
<StatusBar DockPanel.Dock="Bottom" VerticalAlignment="Bottom" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0"/>
<StackPanel Grid.Row="1">
<StatusBar>Status Text</StatusBar>
</StackPanel>
If a StatusBar control in WPF is not positioned at the bottom of the window, there are several potential causes for this issue:
The StatusBar is not placed inside the bottommost container of the window: Make sure the StatusBar is inside the bottommost container of the window, such as a Grid or StackPanel, and that it is placed in the last row of the container.
The container's vertical alignment is not set to "Bottom": Ensure that the container that holds the StatusBar has its VerticalAlignment property set to "Bottom".
The window's height is not being set correctly: Make sure that the window's height is being set correctly, and that it is large enough to accommodate the size of the StatusBar.
The layout of the window is not correct: Check that the layout of the window is correct and that all elements are positioned correctly. You can use the Snapping and Guides feature of the Visual Studio Designer to align elements correctly.
The window is using a template that does not include the StatusBar, if you are using a custom template for the window, check that it includes the StatusBar and that it is positioned correctly.
By troubleshooting these potential causes, you should be able to resolve the issue and position the StatusBar at the bottom of the window.
In my case the order of how I put the children into the Dockpanel had an influence. So, this was the correct order to fill proberly:
<Button DockPanel.Dock="Top" Height="50">Top</Button>
<Button DockPanel.Dock="Bottom" Height="50">Bottom</Button>
<Button DockPanel.Dock="Left" Width="50">Left</Button>
<Button DockPanel.Dock="Right" Width="50">Right</Button>

Resources