Stackpanel height percentage within a grid - c#

I'm dynamically filling two stackpanels with content at runtime and I want to set the height of these two stackpanels via a percentage. Here's what I've tried:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<ScrollViewer HorizontalAlignment="Stretch"
Grid.Row="0">
<StackPanel Name="gridEvents"
Orientation="Vertical"
HorizontalAlignment="Stretch">
<Label Content="Foo" />
</StackPanel>
</ScrollViewer>
<ScrollViewer HorizontalAlignment="Stretch"
Grid.Row="1">
<StackPanel Name="gridNewEvent"
Orientation="Vertical"
HorizontalAlignment="Stretch">
<Label Content="Bar" />
</StackPanel>
</ScrollViewer>
</Grid>
If I change the RowDefinition height to a static value, it works. but not when I try a percentage. Any ideas?

Have you tried setting the height value of your grid? Otherwise it will expand to fill all available space and your rows will fill a percentage of the resulting grid. Also, it looks more like you're setting the value of your scrollviewers. Did you mean to say you were setting the height for those?

Related

WPF Listbox stretching issues

I have created a UserControl that is suppose to display some text and then present a listbox for the user to select some item.
It is supposed to strech to the height to the grid cell it is placed in. And if there are more items than can fit on screen then to display a vertical scrollbar. After much trial and error I have finally managed to get it working as expected. But only when the row height is a pixel value. If I use any partial (by partial I mean the star symbol), the grid cell's height is not contained. Since I need the app the match screen size I need the partials to work.
Putting 100 items in the listbox suddenly makes the height of the entire grid is around 11000 (which I think is everything with no contraint). Meaning there is no scrollbar. See [Screenshot] https://i.stack.imgur.com/faES9.png.
I have a similar issue with my TextBox only horizontally. It will only activate when clicking on a specific pixel since it is empty the width is only 1 pixel. I hope someone can help me point out where I am going wrong, cause since I'm having more than one issue I suspect the problem is on my end.
This is my XAML code.
<UserControl x:Class="PackingStation.UserControls.SearchItemListing"
x:Name="SearchItemListingRoot"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PackingStation.UserControls"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1000">
<Grid DataContext="{Binding ElementName=SearchItemListingRoot}"
x:Name="TheGrid"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".1*" />
<RowDefinition Height=".1*" />
<!-- If this value isnt a pixel value it will not vertically strech to available space -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center"
Margin="0,0,0,0"
x:Name="TheHeadLineField"
Grid.Row="0"
Grid.Column="1">
<Label Style="{StaticResource LabelStyleHeadline32}"
Content="{Binding Title}"
HorizontalAlignment="Left"/>
<Label Style="{StaticResource LabelStyleText}"
HorizontalAlignment="Left"
Content="{Binding SubTitle}"
FontSize="20"/>
</StackPanel>
<!-- Search Field -->
<Border Style="{StaticResource Border6}"
x:Name="TheSearchField"
Grid.Row="1"
Grid.Column="1"
Background="{StaticResource ColorSummaryPanelBackground}"
BorderBrush="{StaticResource ColorSummaryPanelBorder}"
BorderThickness="1"
Margin="0,40,0,0">
<StackPanel Orientation="Horizontal"
Height="78"
HorizontalAlignment="Stretch">
<Image Stretch="Uniform"
Height="24"
Source="pack://application:,,,/WpfUI;component/Icons/Search.png"
Margin="36,0,0,0"
VerticalAlignment="Center"/>
<!-- Search Textbox -->
<!-- Similar issue with this textbox, only horizontally. With no content you have to hit a specific pixel to activate it -->
<TextBox Style="{StaticResource TextBoxSearchInlay}"
Name="TbxSearchTerm"
TextChanged="TextBoxBase_OnTextChanged"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="20,0,0,0"/>
</StackPanel>
</Border>
<!-- Search results listings -->
<ListBox ItemsSource="{Binding Items}"
x:Name="TheListBox"
Grid.Row="2"
Grid.Column="1"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" Margin="0,-10,0,-10">
<Label Style="{StaticResource LabelSearchItem}"
Content="{Binding Name}"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
I could repro your problem when I put your UserControl in a StackPanel. When it's in a Grid the ListBox shows its vertical scrollbar. So, try your UserControl in a Grid.
I think this answer will give a good explanation about Grid and StackPanel stretching behavior.

How to structure a stacked form with WPF XAML?

On my Window, I've got a GroupBox. I'd like to build out a horizontally aligned form inside of that GroupBox. By horizontally aligned, I mean a form where the label and the input reside on the same grid row or x axis. Separate form labels + inputs reside on their own row.
Since a GroupBox can only have one child content, I assume I need to either use a Grid or StackPanel. I'm trying to use a StackPanel because that seems simpler and should achieve what I'm aiming for.
The issue I'm trying to figure out is how to group the input and label into one unit so they can reside horizontally next to each other, but stack vertically as a pair within the StackPanel.
It's probably best to use a Grid that way you an get the labels and inputs to line up vertically. While it's not impossible with a stack panel it's a whole lot harder. If you set the grid's RowDefinition heights to "Auto" the grid will only be as tall as it needs to be:
<GroupBox>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Label1"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Input1}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Label2"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Input2}"/>
etc.
</Grid>
</GroupBox>
You'll probably need to play around with margins and/or padding and horizontal alignments to get the layout exactly how you want it, but this should give you the control you need to achieve what you want.
you can use a stackpanel with orientation equal to vertical inside your groupbox and inside that stackpanel you can have another stackpanel with orientation equal to horizantal for your label and input just like following sample code.
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical">
<StackPanel Name="input1" Orientation="Horizontal">
<Label Content="input1"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input2" Orientation="Horizontal">
<Label Content="input2"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input3" Orientation="Horizontal">
<Label Content="input3"/>
<TextBox/>
</StackPanel>
</StackPanel>
</GroupBox>
One feature you might find useful is grid shared size scope. It can help you align elements in multiple different Grids, by sharing their column\row sizes, like this:
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical" Grid.IsSharedSizeScope="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input11" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input2222222" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input3333333333333" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
</StackPanel>
</GroupBox>
I don't say that it is necessary in the code above, but that is just example. Often, you want to use grid in for example ItemTemplate of ItemsControl, and you want all items to be aligned. Here shared size scope might help.

How to centered Content from Label

I have a Grid:
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="10*"></RowDefinition>
<RowDefinition Height="80*"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Content="Text to center!" BorderBrush="Blue" BorderThickness="5">
</Label>
</Grid>
But at that variant I have a Label from all the Grid rows, but its Content goes to left side of the row.
How to make the Content centered ?
If I type HorizontalAlignment="Center" Label will be centered, but I need only Content.
To set the horizontal alignment of the control's content use Control.HorizontalContentAlignment Property like this:
HorizontalContentAlignment="Center"
HorizontalContentAlignment="Center"

Making vertical nested scroll always visible

I have the following Xaml. I have a grid containing some "columnheaders" and a list box. Currently my horizontal scroll bar scroll both the column headers and the listbox. My vertical scroll bar only scrolls the listbox as I want the column header "frozen". The issue I have is that I have to scroll all the way to the right to see the vertical scroll bar. Is there anyway of "locking" the vertical scroll bar to be always visible ( when its required ) and for it to only scroll the listbox? Please let me know if you need anymore information.
<Grid Name="test1" Margin="0,0,50,0" Grid.Row="0">
<ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Auto" Width="{Binding ElementName=test1, Path=ActualWidth}">
<Grid Name="grdMain" >
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="90*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ItemsControl Name="ColumnHeaders" ..>
</ItemsControl>
</StackPanel>
<StackPanel Name="check" Grid.Row="1">
<ScrollViewer Height="{Binding ElementName=check, Path=ActualHeight}" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Hidden">
<ListBox Name="lstDrop" ..>
</ListBox>
</ScrollViewer>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
Here are screen shots of current functionality:
Finally, it was a bit nastier as I thought. Nevertheless, here is some stuff. I had to do some changes on the initial idea and your layout, but afterwards it'll look all the same.
<Grid Name="test1" Margin="0,0,50,0" Grid.Row="0">
<Grid Name="grdMain" >
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="90*" />
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden" Name="scv_headers">
<ItemsControl Name="ColumnHeaders">
<!--Headers here-->
</ItemsControl>
</ScrollViewer>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" ScrollChanged="List_OnScrollChanged">
<ListBox Name="lstDrop">
<!--Items here-->
</ListBox>
</ScrollViewer>
</Grid>
</Grid>
Because the scrollbars are hidden in the template, I had to add some code behind
private void List_OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
var scrollbarSrc = (ScrollBar)((ScrollViewer)e.OriginalSource).Template.FindName("PART_HorizontalScrollBar", (ScrollViewer)e.OriginalSource);
scv_headers.ScrollToHorizontalOffset(scrollbarSrc.Value);
}
Because your stackpanels only contain one item, I left them away which looks pretty much the same.

Using TextWraping within a TextBox, inside a Grid for use within a ListBox in WP7

I am trying to get my data to display properly within a GridLayout, which is to be used as a DataTemplate for an Item within ListBox. Here is the code associated with what I am doing:
<Grid Name="FeedItemTemplate">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ProfileImage}" Grid.RowSpan="2" Height="75" Width="75" VerticalAlignment="Center" Margin="1" />
<TextBlock Text="{Binding UserName}" Grid.Column="1" Foreground="#FFC8AB14" FontSize="28" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding TimeStamp}" Grid.Column="2" TextWrapping="Wrap" FontSize="18" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Message}" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" TextWrapping="Wrap" FontSize="24" />
</Grid>
The issue is that using this layout, when TextWrapping is set to Wrap, the Item is displayed correctly, but when scrolling through the ListBox everything is really jittery, you cannot scroll in small increments, and it just jumps all over the place.
Any reason why it does this? As I said, only when TextWrapping is set to Wrap it does this. When its not used, it scrolls fine, but the text is all along one line and off the screen.
Does it keep jumping if you explicitly set the top-level Grid element's width to a fixed size?
For some reason that I do not fully understand, settings the ListBox's ItemsPanel property to a StackPanel might solve your problem:
<UserControl.Resources>
<ItemsPanelTemplate x:Key="MyItemsPanelTemplate">
<StackPanel/>
</ItemsPanelTemplate>
</UserControl.Resources>
...
<ListBox ... ItemsPanel="{StaticResource MyItemsPanelTemplate}"/>
This is a known issue with listbox scrolling in the current ctp when you have variable height items. The workaround for now is to set a fixed height on your listbox item content. You'll probably also notice the scroll bar doesnt properly go to the bottom all the time. The workaround fixes that too.
Reference.

Categories