How to divide stackpanel in 7 equal height rectangles - xaml

I am working on Windows Phone 8 app wherein I have a Stackpanel and I want to put 7 rectangles in it. I want those rectangles to be of equal height irrespective of screen size. I tried setting Height="*" but it is giving error.
<StackPanel>
<Rectangle Fill="Violet" Height="*"></Rectangle>
<Rectangle Fill="Indigo" Height="*"></Rectangle>
<Rectangle Fill="Blue" Height="*"></Rectangle>
<Rectangle Fill="Green" Height="*"></Rectangle>
<Rectangle Fill="Yellow" Height="*"></Rectangle>
<Rectangle Fill="Orange" Height="*"></Rectangle>
<Rectangle Fill="Red" Height="*"></Rectangle>
</StackPanel>
Can anyone help me with it?

The following should do it for you:
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*">
<RowDefinition Height="*">
<RowDefinition Height="*">
<RowDefinition Height="*">
<RowDefinition Height="*">
<RowDefinition Height="*">
<RowDefinition Height="*">
<Grid.RowDefinitions>
<Rectangle Fill="Violet" Grid.Row="0" />
<Rectangle Fill="Indigo" Grid.Row="1" />
<Rectangle Fill="Blue" Grid.Row="2" />
<Rectangle Fill="Green" Grid.Row="3" />
<Rectangle Fill="Yellow" Grid.Row="4" />
<Rectangle Fill="Orange" Grid.Row="5" />
<Rectangle Fill="Red" Grid.Row="6" />
</Grid>
There is also a UniformGrid that can do this for you:
<UniformGrid Columns="1" Rows="7" />

Related

How to Bind to Height with "auto" value

Working with UWP means I cant use DIP values always. I rely on "auto" sizes, "Stretch" alignments, etc.
I narrowed my problem to this:
How Can I Bind Height and Width of Element to Another Element, which has Height and Width "Auto"?
Sample:
<Grid.RowDefinitions>
<RowDefinition x:Name="CardGriddRow1" Height="2*" />
<RowDefinition x:Name="CardGrdidRow2" Height="1*" />
</Grid.RowDefinitions>
<Rectangle Name="Rec1" Fill="Blue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="auto" Height="auto" Grid.Row="1" Margin="20" />
<Rectangle Name="Rec2" Fill="Yellow" Grid.Row="0" Height="{x:Bind Rec1.ActualHeight, Mode=OneWay }" Width="{x:Bind Rec1.ActualWidth, Mode=OneWay }" HorizontalAlignment="Left" VerticalAlignment="Top" />
When using ActualHeight, I can use only OneWay mode. Height value is NaN.
Rec2 will have 0 values but ActualHeight of Rec1 is more than 0.
Is there way to force Binding to take ActualHeight?
How Can I Bind Height and Width of Element to Another Element, which has Height and Width "Auto"?
ActualHeight is a calculated property. For purposes of ElementName binding, ActualHeight does not post updates when it changes (due to its asynchronous and run-time calculated nature). Do not attempt to use ActualHeight as a binding source for an ElementName binding. If you have a scenario that requires updates based on ActualHeight, use a SizeChanged handler. Details please reference ActualHeight property.
Although updated your code snippet to use binding instead as follows, it seems like worked , but it is not reliable that you should not use it .
<Rectangle Name="Rec1" Fill="Blue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1" Margin="20" Height="auto" Width="auto" />
<Rectangle Name="Rec2" Height="{Binding Path=ActualHeight,ElementName=Rec1}" Width="{Binding Path=ActualWidth,ElementName=Rec1}" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Yellow" Grid.Row="0"/>
The correct way as the document mentioned, you could use SizeChanged, for example:
<Rectangle Name="Rec1" SizeChanged="Rec1_SizeChanged" Fill="Blue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1" Margin="20" Height="auto" Width="auto" />
<Rectangle Name="Rec2" Fill="Yellow" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" />
Code behind:
private void Rec1_SizeChanged(object sender, SizeChangedEventArgs e)
{
Rec2.Height = Rec1.ActualHeight;
Rec2.Width = Rec1.ActualWidth;
}
I would try to avoid the SizeChanged event as much as possible as it fires so often when the screen is resized it can cause the UI to start freezing and drop in frame rate. Let the Xaml do as much of the work as possible. I've recreated the scenario you've shown in the link you attached in your comment using Xaml only. See screenshot:
It may not be exactly the same as yours but with some styling it could be.
See code:
<Page>
<Page.Resources>
<Style TargetType="Rectangle">
<Setter Property="VerticalAlignment"
Value="Stretch"/>
<Setter Property="HorizontalAlignment"
Value="Stretch" />
</Style>
</Page.Resources>
<Grid Background="Blue">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="8">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0"
Grid.Column="1"
Fill="Red" />
<Rectangle Grid.Row="0"
Grid.Column="2"
Fill="Yellow" />
</Grid>
<Rectangle Grid.Row="2"
Grid.Column="0"
Fill="Blue" />
<Rectangle Grid.Row="2"
Grid.Column="1"
Fill="Red" />
<Rectangle Grid.Row="2"
Grid.Column="2"
Fill="Green" />
<Rectangle Grid.Row="2"
Grid.Column="3"
Fill="Yellow" />
<Rectangle Grid.Row="2"
Grid.Column="4"
Fill="Brown" />
<Rectangle Grid.Row="2"
Grid.Column="5"
Fill="Pink" />
<Rectangle Grid.Row="2"
Grid.Column="6"
Fill="Purple" />
<Rectangle Grid.Row="2"
Grid.Column="7"
Fill="Orange" />
</Grid>
</Page>

Extra space under bottom positioned TextBlock (Windows Phone 8)

I have a problem with positioning the TextBlock element on the bottom of the newsfeed rectangle.
I attached the image of the problem (red arrow is pointing at it). There is too much extra space at the bottom of the "timeago" TextBlock.
You can see that the problem only occurs when the movie title is short enough to fit into first line.
I would guess that this makes the StackPanel to shrink and therefore move the TextBlock with time elapsed a bit higher.
I tried changing the MinHeight of parent StackPanel to lower values or even removing the property, but it doesn't seem to work.
I am guessing that the problem is with the "inner" StackPanel containing the content, stars (not visible) and "timeago"
This is the DataTemplate of my LongListSelector
<DataTemplate>
<Grid Margin="12,2,5,4" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Fill="{StaticResource PhoneAccentBrush}"
Opacity="0.75"
Margin="0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<StackPanel Grid.Row="0" Orientation="Horizontal"
Background="Transparent"
Height="auto"
MinHeight="99"
Width="auto">
<Grid HorizontalAlignment="Center"
Background="#FFFFC700"
Height="auto"
Width="99">
<Image Source="{Binding ImageUrl}"
Height="auto"
Width="auto"
Stretch="UniformToFill"
Margin="0"
HorizontalAlignment="Center"
VerticalAlignment="Stretch">
</Image>
</Grid>
<StackPanel Width="311" Margin="8,-7,0,0">
<TextBlock Margin="10,15,15,0" Text="{Binding Content}" Style="{StaticResource NewsFeedHighlitedContent}" FontSize="24" />
<Grid Margin="10,5,0,15" Visibility="{Binding StarsVisibility}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Image Source="{Binding StarOne}" Height="30" Margin="0,0" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="0" />
<Image Source="{Binding StarTwo}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="1" />
<Image Source="{Binding StarThree}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="2" />
<Image Source="{Binding StarFour}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="3" />
<Image Source="{Binding StarFive}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="4" />
</Grid>
<TextBlock Text="{Binding Time}" Margin="8,14,25,7" VerticalAlignment="Bottom" Style="{StaticResource NewsTimeAgoStyle}" />
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
And the style for "NewsTimeAgoStyle"
<Style x:Key="NewsTimeAgoStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="20"/>
<Setter Property="FontFamily" Value="Segoe WP Light" />
<Setter Property="Margin" Value="0,14,20,0" />
<Setter Property="Opacity" Value="0.8" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
Does anybody have any clue on how to solve this problem?
I am not sure but the problem might be because you are using StackPanel to display title and time ago text. I have changed your DataTemplate little bit to use Grid Panel. Try this and see this make any difference
<DataTemplate>
<Grid Margin="12,2,5,4" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Fill="{StaticResource PhoneAccentBrush}"
Opacity="0.75"
Margin="0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<Grid Grid.Row="0"
Background="Transparent"
Height="auto"
MinHeight="99">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="99"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid HorizontalAlignment="Center"
Background="#FFFFC700">
<Image Source="{Binding ImageUrl}"
Height="auto"
Width="auto"
Stretch="UniformToFill"
Margin="0"
HorizontalAlignment="Center"
VerticalAlignment="Stretch">
</Image>
</Grid>
<Grid Width="311" Margin="8,-7,0,0" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Margin="10,15,15,0" Text="{Binding Content}" Style="{StaticResource NewsFeedHighlitedContent}" FontSize="24" />
<Grid Margin="10,5,0,15" Visibility="{Binding StarsVisibility}" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Image Source="{Binding StarOne}" Height="30" Margin="0,0" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="0" />
<Image Source="{Binding StarTwo}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="1" />
<Image Source="{Binding StarThree}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="2" />
<Image Source="{Binding StarFour}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="3" />
<Image Source="{Binding StarFive}" Height="30" Width="30" Stretch="UniformToFill" Grid.Row="0" Grid.Column="4" />
</Grid>
<TextBlock Text="{Binding Time}" Margin="8,14,25,7" Grid.Row="2" VerticalAlignment="Bottom" Style="{StaticResource NewsTimeAgoStyle}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>

Grid adding unwanted extra vertical space

I have the following xaml inside a user control:
<StackPanel VerticalAlignment="Top">
<Grid Background="LimeGreen">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" VerticalAlignment="Top" Fill="Yellow" Width="80" Height="80" />
<Rectangle Grid.Column="1" Grid.Row="0" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Column="1" Grid.Row="2" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
</Grid>
</StackPanel>
and it produces the following layout:
For some reason, this is adding extra unwanted space after the yellow square. I want the following layout instead:
The extra space only occurs when the green grid is inside a stack panel. I can get the correct layout by either:
Putting the green grid inside a grid instead of a stack panel.
Or setting the width of the second column to "Auto". This is undesired, though.
My questions are:
Is the layout in the first picture correct/expected? If so, why is it adding the extra space?
Why does setting the width of the second column to "Auto" get rid of the extra vertical space?
How can I get layout #2 inside a stack panel with width of second column set to * (star)?
I can answer question 3 with this alternative xaml, however it uses a nested grid to bypass using a row span for the yellow square. Ideally this should be possible using just one grid. Anyway, here's the xaml:
<StackPanel VerticalAlignment="Top">
<Grid Background="LimeGreen">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle VerticalAlignment="Top" Fill="Yellow" Width="80" Height="80" />
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Row="1" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Row="2" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
</Grid>
</Grid>
</StackPanel>
I'm still stumped on answering questions 1 and 2.

XAML UI Button. Resizible image and Text

I have tried to create a xaml UI layout that has buttons, at the moment TILEs. They should have image and text, and both of them should resize according the screen size.
How would you add resizable text/header/title to this?
Thank you for in advance.
<Grid Grid.Column="0" x:Name="MenuGrid" UseLayoutRounding="True" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="3*" MaxHeight="150"/>
<RowDefinition Height="3*" MinHeight="75" />
<RowDefinition Height="3*" MinHeight="75" />
<RowDefinition Height="3*" MinHeight="75" />
</Grid.RowDefinitions>
<Image RenderOptions.BitmapScalingMode="Fant" Grid.Column="0" Grid.Row="0" Source="/Resources/logo.png" VerticalAlignment="Stretch" StretchDirection="DownOnly"/>
<controls:Tile Name="tileInvoice" Width="Auto" Height="Auto" Grid.Row="1" VerticalAlignment="Stretch" Margin="0,0,0,0" ToolTip="Invoice">
<controls:Tile.Background>
<ImageBrush Stretch="Uniform" ImageSource="/Resources/invoice.png"/>
</controls:Tile.Background>
</controls:Tile>
<controls:Tile Name="tileCustomer" Width="Auto" Height="Auto" Grid.Row="2" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="0,0,0,0">
<controls:Tile.Background>
<ImageBrush Stretch="Uniform" ImageSource="/Resources/customer.png" />
</controls:Tile.Background>
</controls:Tile>
<controls:Tile Name="tileItem" Width="Auto" Height="Auto" Grid.Row="3" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="0,0,0,0">
<controls:Tile.Background>
<ImageBrush Stretch="Uniform" ImageSource="/Resources/item.png"/>
</controls:Tile.Background>
</controls:Tile>
</Grid>
This is not MahApps specific, it's about xaml layout. If you want scalable controls wrap them in a Viewbox
<Viewbox>
<controls:Tile Name="tileInvoice" Width="Auto" Height="Auto" Grid.Row="1" VerticalAlignment="Stretch" Margin="0,0,0,0" ToolTip="Invoice">
<controls:Tile.Background>
<ImageBrush Stretch="Uniform" ImageSource="/Resources/invoice.png"/>
</controls:Tile.Background>
</controls:Tile>
</Viewbox>
I got it working with this code.
<Viewbox Grid.Row="1">
<controls:Tile Name="tileInvoice" Click="tileInvoice_Click" VerticalAlignment="Stretch" ToolTip="{x:Static resx:omniLang.Invoice}">
<controls:Tile.Background>
<ImageBrush ImageSource="Resources/invoice.png" Stretch="Uniform"/>
</controls:Tile.Background>
<TextBlock Name="headerInvoice" Text="{x:Static resx:omniLang.Invoice}" FontSize="22" Foreground="Black" FontWeight="Bold" VerticalAlignment="Center" Margin="0,100,0,0" />
</controls:Tile>
</Viewbox>

GridSplitter in a Frame; expand beyond border problems

I've got a generic view for displaying data in a Silverlight RIA application. Basically, the view takes in a parameter which is the query required by RIA to get the data, and the data is displayed using autogenerated fields.
Here's part of the XAML code for the view.
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition x:Name="DataGridRow"/>
<RowDefinition Height="Auto"/>
<RowDefinition x:Name="DataFormRow"/>
<RowDefinition Height="Auto" x:Name="EditRow"/>
</Grid.RowDefinitions>
<ria:DomainDataSource Name="SQLDomainDataContext" LoadingData="SQLDomainDataContext_LoadingData" LoadSize="45" SubmittedChanges="SQLDomainDataContext_SubmittedChanges" SubmittingChanges="SQLDomainDataContext_SubmittingChanges" LoadedData="SQLDomainDataContext_LoadedData">
<ria:DomainDataSource.SortDescriptors>
<ria:SortDescriptor Direction="Descending" PropertyPath="BaseProperties.CreatedOn" />
</ria:DomainDataSource.SortDescriptors>
</ria:DomainDataSource>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<sdk:DataGrid Grid.Row="0" AutoGenerateColumns="True" Name="dataGrid" ItemsSource="{Binding}" DataContext="{Binding Path=Data, Mode=TwoWay}" IsReadOnly="True" AutoGeneratingColumn="dataGrid_AutoGeneratingColumn" SelectionChanged="dataGrid_SelectionChanged" />
<custCont:LocalizedDataPager Grid.Row="1" x:Name="pager" Source="{Binding Path=Data}" PageSize="15" DisplayMode="FirstLastPreviousNext" />
</Grid>
<Border Grid.Row="1">
<Border.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FF9D9D9D" Offset="0" />
<GradientStop Color="#FFDBDBDB" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Ellipse Fill="Black" HorizontalAlignment="Center" Width="4" Height="4" Margin="8,0"/>
<Ellipse Fill="Black" HorizontalAlignment="Center" Width="4" Height="4" Margin="8,0"/>
<Ellipse Fill="Black" HorizontalAlignment="Center" Width="4" Height="4" Margin="8,0"/>
</StackPanel>
</Border>
<sdk:GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" Background="Transparent" Opacity="0"/>
<data:DataForm Grid.Row="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="DF" AutoCommit="False"
DataContext="{Binding Path=Data, Mode=TwoWay}" ItemsSource="{Binding}"
AutoGeneratingField="DF_AutoGeneratingField" EditEnded="DF_EditEnded" DeletingItem="DF_DeletingItem" Style="{StaticResource DataFormStyle}"/>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Name="btnHideDF" Content="{Binding Source={StaticResource ApplicationResources}, Path=ApplicationStrings.ShowEntities_HideDfBtn}" MinWidth="10" Margin="2" Click="btnHideDF_Click" />
<Button Grid.Column="2" Name="bRefresh" Content="{Binding Source={StaticResource ApplicationResources}, Path=ApplicationStrings.ShowEntities_RefreshBtn}" MinWidth="75" Margin="2" Click="bRefresh_Click" IsEnabled="{Binding Path=CanLoad}" />
<Button Grid.Column="3" Name="btnCacnelChanges" Content="{Binding Source={StaticResource ApplicationResources}, Path=ApplicationStrings.ShowEntities_CancelChangesBtn}" Margin="2" IsEnabled="{Binding Path=HasChanges}" Click="btnCacnelChanges_Click" Visibility="Collapsed" />
<Button Grid.Column="4" Name="bSubmit" Content="{Binding Source={StaticResource ApplicationResources}, Path=ApplicationStrings.ShowEntities_SubmitBtn}" MinWidth="75" Margin="2" IsEnabled="{Binding Path=HasChanges}" Click="bSubmit_Click" />
</Grid>
</Grid>
When the view is displayed in a singular Frame, all is well. But when it is displayed on a page with TWO frames, odd things begin to happen. If the user grabs the splitter and moves it all the way to the top, beyond the frames boundaries, the DataForm will expand endlessly. This isn't a big issue, but it looks ugly, and makes the buttons at the bottom vanish from sight.
What's going on here? Why is this happening? How can I prevent this behaviour?
Apparently my Google-fu was weak.
I found this today, and it describes the exact same problem I had, as well as a possible solution.
Still, I didn't expect this to be a bug in SL...