How can use flow layout inside of a ScrollViewer? - wpf

I have a situation with a scroll viewer, and a wrap panel inside of that scroll viewer. The intended behavior is that the content does not scroll left and right, only up and down, and that content wraps (becomes taller) as necessary.
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" Margin="0">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="330" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="74" />
<RowDefinition Height="75" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- ... other stuff ... -->
<WrapPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="35,0,0,0">
<Button Style="{StaticResource CreateModelButtonStyle}"
CommandParameter="Design"
Command="{StaticResource WindowProfileUnconditional}">
<StackPanel>
<TextBlock Style="{StaticResource HomePageButtonMarqeeTextStyle}" Text="Blah Blah"/>
<TextBlock Style="{StaticResource HomePageButtonDescriptionTextStyle}" Text="Blah Blah" />
</StackPanel>
</Button>
<!-- A bunch more buttons -->
</WrapPanel>
<!-- ... other stuff ... -->
</Grid>
</ScrollViewer>
The behavior I get instead is that the scroll viewer tells the wrap panel that it can be any width, so the wrap panel behaves like a stack panel and clips instead of wraps.
Is there some way to allow vertical scrolling while completely preventing horizontal scrolling?

Why don't you bind the Width of your WrapPanel (or Grid) to the Width of the ScrollViewer?
<ScrollViewer x:Name="MyScrollViewer" ...>
<WrapPanel Width="{Binding ElementName=MyScrollViewer, Path=Width}" ... />
</ScrollViewer>
Not positive if you need to bind to Width or ActualWidth. If one doesn't work, try the other one.

Related

status bar disappears after populating datagrid

I have user controls that contains datagrid.
My status bar disappears as soon as grid populates even though I have enough margins and there's empty space at the bottom. What am i doing wrong????
<DockPanel VerticalAlignment="Stretch" LastChildFill="False">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="0,0,0,0">
<controls:ucXXXXSummary x:Name="ucSummary" Margin="20,20,20,30" Height="Auto" Width="Auto"/>
<controls:XXXXUC x:Name="ucXXXX" Margin="20,20,20,30" Height="Auto" Width="Auto"/>
</StackPanel>
<StatusBar DockPanel.Dock="Bottom" Height="25">
<StatusBarItem>
<StatusBarItem>
<TextBlock Name="lblStatus" Text="abc!!!!!!!!!!!"/>
</StatusBarItem>
</StatusBarItem>
</StatusBar>
</DockPanel>
Don't rely on margins to position elements relative to each other. Use an appropriate Panel such as for example a Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:ucXXXXSummary x:Name="ucSummary" Margin="20,20,20,30" />
<controls:XXXXUC Grid.Row="1" x:Name="ucXXXX" Margin="20,20,20,30" />
<StatusBar Grid.Row="2" Height="25">
<StatusBarItem>
<StatusBarItem>
<TextBlock Name="lblStatus" Text="abc!!!!!!!!!!!"/>
</StatusBarItem>
</StatusBarItem>
</StatusBar>
</Grid>
StackPanels don't play well with scrollable content: Horizontal scroll for stackpanel doesn't work

Avoid WPF statusbar gets totally collapsed when window gets resized vertically to a smaller size

I have below WPF window which contains a dockpanel as main container. Then I place a main grid at the top (which contains some other grids) and a statusbar at the bottom.
<Window>
<DockPanel>
<Grid DockPanel.Dock="Top">
<!-- Grid stuff here -->
</Grid>
<StatusBar DockPanel.Dock="Bottom"
VerticalAlignment="Bottom">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="0">
<TextBlock Text="Item1"/>
</StatusBarItem>
<Separator Grid.Column="1" />
<StatusBarItem Grid.Column="2">
<TextBlock />
</StatusBarItem>
<Separator Grid.Column="3" />
<StatusBarItem Grid.Column="4">
<TextBlock Text="AnotherItem" />
</StatusBarItem>
</DockPanel>
</Window>
I have below problem:
When window is resized vertically to a smaller size, there comes a moment in which statusbar height is reduced and even completely collapsed. So how to avoid this? I want statusbar never gets collapsed and keep all the time its height.
Grids within Grids are so hot right now.
<Window x:Class="GridRoot.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Border BorderBrush="Black" BorderThickness="10" Background="CornflowerBlue">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
Hello!
</TextBlock>
</Border>
</Grid>
<StatusBar Grid.Row="1">
<StatusBarItem>
<TextBlock>
GET OFF ME!
</TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>
The top row takes up as much space is available, and the bottom row takes up as much space as its content desires. Since the StatusBar control pretty much has a set height, it will always stay visible on the bottom.
Some folks might have issue with putting a Grid inside another Grid, but there's absolutely no reason not to.
The above example, tiny
and embiggened

WPF: Inner content wont scroll

I have a Window with a Grid inside:
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="70" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding ChildViewModel.View}" />
<DockPanel Grid.Row="1" Visibility="{Binding SearchResultViewVisibility}">
<GridSplitter DockPanel.Dock="Top" Background="LightGray" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsTabStop="False"/>
<Views:SearchResultView DataContext="{Binding SearchResultViewModel}" />
</DockPanel>
<UserControls:GradientBackgroundControl Grid.Row="2" Height="25">
<Validators:FocusSummaryControl x:Name="FocusSummary" ValidateOnlyFocusedElement="False" />
</UserControls:GradientBackgroundControl>
</Grid>
The ContentControl gets a UserControl with this Grid set:
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="0" Grid.ColumnSpan="4">
<StackPanel>
...
</StackPanel>
</ScrollViewer>
The problem now is, that the ScrollViewer in the UserControl doesn't scroll. The content of the UserControl set to the ContentControl is heigher and the overflow ist just hidden.
If I am not wrong, StackPanel requires a Height to be set for scroll functionality to work because StackPanel, by design, grows in one direction (based on Orientation).
To confirm whether this is the cause of your problem, please test by setting the height of StackPanel to a fixed height. Alternately, you may want to replace the StackPanel with say DockPanel and see the behaviour. Also there is a ScrollViewer.CanContentScroll property that you may want to fiddle with.
Let us know the result of this test.
I think you need to rearrange things a little bit. My suggestions (I'm sure there are infinite variations that would work):
First, add a new row to your grid (Height="Auto") and set the height of your top row (with your ContentControl in it) to "*"
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="70" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
Second, move your GridSplitter out of the DockPanel. Put the splitter in row 1 and the dockpanel in row 2.
<ContentControl Grid.Row="0" Content="{Binding ChildViewModel.View}" />
<GridSplitter Grid.Row="1" Background="LightGray" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsTabStop="False" ResizeBehavior="PreviousAndNext"/>
<DockPanel Grid.Row="2" Visibility="{Binding SearchResultViewVisibility}">
<Views:SearchResultView DataContext="{Binding SearchResultViewModel}" />
</DockPanel>
Note that you'll probably also have to set the ResizeBehavior for your GridSplitter as shown above. I hope this will get you close to what you want.

Silverlight 4, XAML: How to extend <toolkit:BusyIndicator> to several grid columns?

So I have a following XAML code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="214" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="42" />
</Grid.RowDefinitions>
<toolkit:BusyIndicator IsBusy="False" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<StackPanel Grid.Column="0" Grid.Row="0">
<!-- ... -->
</StackPanel>
<Canvas Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- ... -->
</Canvas>
</toolkit:BusyIndicator>
<TextBlock Grid.Row="1" Grid.ColumnSpan="2" />
</Grid>
The idea is to have BusyIndicator to cover both cells in the first row and leave second row as is. But XAML editor in Visual Studio underlines <Canvas> and says: "The property 'Content' is set more than once."
How to overcome this?
You're getting the error about 'Content' being set more than once because a BusyIndicator is a ContentControl and can only have at most one child.
What you can do instead is put the BusyIndicator inside the grid as siblings of your StackPanel and Canvas. To ensure that it appears above the other controls in the top row when it is busy, use the property Canvas.ZIndex. This needs to have a higher Z-index than any controls within your stackpanel and canvas. (If you're not using Z-indexes in your stackpanel and canvas, 1 will do, as in the example below.)
<Grid>
<!-- ... -->
<toolkit:BusyIndicator IsBusy="False" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Canvas.ZIndex="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/ >
<StackPanel Grid.Column="0" Grid.Row="0">
<!-- ... -->
</StackPanel>
<Canvas Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- ... -->
</Canvas>
<TextBlock Grid.Row="1" Grid.ColumnSpan="2" />
</Grid>

Silverlight PivotItem not scrolling down

PivotItem can't scroll down... Anyone has any ideas as to how I can remedy this?
For whatever the reason just won't scroll down when content that is bound inside the listbox is longer than the height of the page. I tried adding a grid inside the pivotitem with height set to auto, but to no avail.
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<controls:Pivot Height="Auto">
<controls:PivotItem Header="Main Information">
<Border CornerRadius="10" Background="#FF5C7590" Height="Auto" Padding="2" BorderThickness="1">
<ListBox x:Name="lbxPropertyItems">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="5, 0, 0, 0" Grid.Column="0" Text="{Binding Label}" />
<TextBlock Grid.Column="1" Text="{Binding Value}" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</controls:PivotItem>
</controls:Pivot>
</Grid>
Thanks for any advice.
The issue is that a StackPanel has an infinite layout space in which ever orientation it is set, so the ScrollViewer included in the ListBox never gets activated in that direction. The best way to handle it is to host it inside a Grid control with row or column definitions.

Resources