Listbox is not getting a vertical scrollbar - c#

The main issue people seem to have with the vertical scrollbar not appearing is because they use a stackpanel. I went through my complete visual tree and my listbox is not in a stackpanel anywhere.
Here is the XAML that I use:
<Grid>
<Grid.Resources>
<local:ReportToListItem x:Key="reportToListItem" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="3" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Background="PaleGoldenrod" x:Name="Controller_Domain_Reports_OpenReports">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding Converter={StaticResource reportToListItem}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border Grid.Row="1" Background="Black" Height="3" HorizontalAlignment="Stretch" />
<ListBox Background="Magenta" Grid.Row="2" x:Name="Controller_Domain_Reports_ClosedReports">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding Converter={StaticResource reportToListItem}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Neither listbox gets a scrollbar if it extends beyond the height of the window for me. What am I overlooking?

Just putting this up to close this off properly:
Do'h.. The shellview had a nice copy pasted list of rowdefinitions all set to auto. Changed the one that contains this view to * and now it works as expected.

Related

Add row of text above a grid of items

I'm building a grid via WPF, and it works great. I need to add a row, or bar, or something to display above the grid, that will have several text items on it that will get populated by code. I've been tooling around, and I can't seem to figure out how to put another panel above my existing (and working) grid. This is my code:
<Window x:Class="GridWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Board" SizeToContent="WidthAndHeight" Height="Auto" Width="Auto">
<Window.Resources>
<DataTemplate x:Key="DataTemplate_2">
<Button Content="{Binding}" Height="25" Width="25" Margin="0,0,0,0"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid Name="GridBoard" ShowGridLines="True">
<ItemsControl x:Name="GridItems" ItemTemplate="{DynamicResource DataTemplate_1}"/>
</Grid>
</Window>
The GridItems gets populated by a jagged array, and displays fine. I just need to put a few text objects above it, be it boxes, or just a horizontal panel that fits the width of the grid.
May be the simplest option is to add a wrapper Grid and put your inner Grid in the second row. So, you will have the first row (row 0) to put anything you need there.
<Window x:Class="GridWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Board" SizeToContent="WidthAndHeight" Height="Auto" Width="Auto">
<Window.Resources>
<DataTemplate x:Key="DataTemplate_2">
<Button Content="{Binding}" Height="25" Width="25" Margin="0,0,0,0"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<!-- WHATEVER YOU NEED -->
</Grid>
<Grid Name="GridBoard" ShowGridLines="True" Grid.Row="1">
<ItemsControl x:Name="GridItems" ItemTemplate="{DynamicResource DataTemplate_1}"/>
</Grid>
</Grid>
There are a few ways to achieve it.
1 - you can add a row and columns to your grid definition:
<Grid.ColumnDefinitions>
<ColumnDefinition width="*" />
<ColumnDefinition width="*" />
<ColumnDefinition width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Then you can just assign 'headers' to each column, like so:
<TextBlock ... Grid.Column="0" />
<TextBlock ... Grid.Column="1" />
<TextBlock ... Grid.Column="2" />
And place your ItemsControl in the second row:
<ItemsControl ... Grid.Row="1" Grid.ColumnSpan="3" />
A half-assed way that may or may not work in your case. No way of knowing without taking a look at the DataTemplate.
2 - StackPanel at the top, with margin applied to the ItemsControl
You can use a similar half-solution - set the top margin of your ItemsControl to a fixed value, like so:
<ItemsControl ... Margin="2,48,2,2" />
And add a StackPanel to your grid:
<StackPanel Height="48" VerticalAlignment="Top">
<TextBlock Text="First Header" Width="300" />
...
</StackPanel>
I'm sure you get the idea.
3 - Use a GridView -RECOMMENDED-
This would require you to change your ItemsControl to a ListView, though.
Here is a well-written tutorial on GridViews for WPF. Granted, it might not be what you're looking for, but again - without knowing what you're trying to present it's difficult to find best solution.
I don't know what you expect the output to look like, but you can nest your "GridBoard" Grid within another Grid. The new outer Grid defines two rows, whereby in the first row you can put your boxes or whatever you like. This could look like this for example:
<Window x:Class="GridWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Board" SizeToContent="WidthAndHeight" Height="Auto" Width="Auto">
<Window.Resources>
<DataTemplate x:Key="DataTemplate_2">
<Button Content="{Binding}" Height="25" Width="25" Margin="0,0,0,0"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="Put something here ..." />
</Grid>
<Grid Grid.Row="1" Name="GridBoard" ShowGridLines="True">
<ItemsControl x:Name="GridItems" ItemTemplate="{DynamicResource DataTemplate_1}"/>
</Grid>
</Grid>
</Window>
Note that you could use any element for the content of the first row of your outer Grid. This depends on your actual needs. In this example I used another Grid which contains a single TextBlock.

Grid in Itemscontrol - WP8

I have problem when using Grid in ItemsControl. Here is my code:
<ItemsControl ItemsSource="{Binding Items}" Margin="12,0,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Name="imgCotrol"
Grid.Row="0"
Source="{Binding Image}"
Margin="0,10,0,10"/>
<TextBlock Grid.Row="1"
Name="txtControl"
Text="{Binding Description}"
TextWrapping="Wrap"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The problem here is that the Grid.RowDefinitions are not affecting the remaining space. The Image control overflows the TextBlock control in some cases.I think the ItemTemplate ignores the Grid rows. I read somewhere that ContentPresenter from the ItemsControl is causing this behavior. How can I resolve this?

WPF Listbox grows outside screen size (MVVM light)

I have a typical MVVM structure. A mainwindow consists of some labels and a viewmodel (bound as ContentControl). This viewmodel has a listbox where I add entries. As the list grows the height of my viewmodel grows as well and thus the height of the whole application. Unfortunately the size doesn't stop at the edge of the screen and just grows out of the screen. I tried all the different size-restrictions on the mainwindow, the viewmodel is stretched in both dimensions.
Furthermore, I tried to get a scrollbar for the listbox but didn't succeed (or it's just there but not enabled if I force it.)
How can I restrict the maximal size to be the resolution of the screen (fullscreen) and get a scrollbar for the listbox when the size is reached?
€: Okay, here should be the relevant part of my code. I tried a fixed size of 1024x768 but even that doesn't work.
MainWindow.xaml
<Window x:Class="SWS.MainWindow"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Width="1024"
Height="768"
MaxWidth="1024"
MaxHeight="768">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
The ViewModel in question
<UserControl x:Class="SWS.Views.ProgramView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<Label Width="65" Content="{x:Static p:Resources.PrV_Number}" />
<Label Width="75" Content="{x:Static p:Resources.PrV_Weight}" />
<Label Width="55" Content="{x:Static p:Resources.PrV_Action}" />
<Label Content=" " />
</DockPanel>
<ListBox Grid.Row="1"
VerticalAlignment="Stretch"
ItemsSource="{Binding ParticleCollection}"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding ID}" Width="53" />
<TextBlock Text="{Binding Weight, StringFormat=F4}" Width="65" />
<TextBlock Text="{Binding Action}" Width="52" />
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
You need to set the row height to * on your Window for ContentControl and your ListBox in UserControl to fill available space than try to get what it needs.
This worked fine:
MainWindow.xaml:
<Window x:Class="SWS.MainWindow"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Width="1024"
Height="768"
MaxWidth="1024"
MaxHeight="768">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
and UserControl:
<UserControl x:Class="SWS.Views.ProgramView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
...
</Grid>
</UserControl>
Could also do this in a couple more ways:
In your Window you can just remove the <Grid.RowDefinitions>...<Grid.RowDefinitions> completely. The default behavior is what your looking for.
When you have more than 1 row you can either choose to specify Height="*" or just remove the Height Property from the RowDefinition
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>

How do I make an empty TextBox stretch vertically?

I want to make a ListBox that arranges items horizontally. Each item should be a TextBox, and it should fill the list box vertically regardless how how much text is there. If you've used Tweetdeck, I'm aiming for a similar effect. Here's what I've got:
<ListBox
Background ="DarkGray"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ItemsSource="{Binding Path=Items}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="2" CornerRadius="5" Margin="2,0,2,0">
<Grid Width="250">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Stretch"
Text="{Binding Path=Messages, Mode=OneWay}" />
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What happens is that the TextBox stubbornly fits the text in it, rather than stretching vertically. I've tried switching the Grid for a DockPanel, which didn't help. I could bind the TextBox's Height property, but that seems unpleasant.
Is there a trick to this that I've missed?
You need to set VerticalContentAlignment="Stretch" on your ListBox.

How to get a footer just above a Scrollviewer?

I got a Scrollviewer with an ItemsControl inside. The ItemsControl, depending on the number of items in it, can be scrolled or not with the SCrollViewer.
I have a Control that display some total values of all the items. This control needs to be just under the ItemsControl. If there is not many items, it will be just under the last, not on the bottom of the page, with a lot of space between.
I can't achieve to do that.
Has anyone any ideas ? Here some of my code :
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<!-- This is my Total Control - just a Border for the example -->
<Grid Margin="0,4" MaxHeight="60" VerticalAlignment="Top" DockPanel.Dock="Bottom">
<Border Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
<ScrollViewer HorizontalContentAlignment="Stretch" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
>
<ItemsControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=ListeQuestions}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<concUCQuest:UCQuestion HorizontalAlignment="Stretch" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
Here is a link to a picture of what i try to get
I tried DockPanel, Grid into Grid, but I've got out of ideas.
Thanks for your help !
Adding a VerticalAlignment="Stretch" to the Scrollviewer should do the trick.
<Grid>
<DockPanel LastChildFill="True">
<!-- This is my Total Control - just a Border for the example -->
<Grid DockPanel.Dock="Bottom">
<Border Background="Red" Height="10"/>
</Grid>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<ItemsControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Grid>
This works for me.
You can also use a ListBox with a DataTemplate, instead of wrapping an ItemsControl with a ScrollViewer.

Categories