How to place two stack panels in grid vertically? - c#

i am placing a grid like this in a grid of 1st column
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Image Source="{Binding PictureUrl}" Width="100" Height="100" Stretch="Fill" HorizontalAlignment="Left"></Image>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1">
<HyperlinkButton Content="{Binding Path=GeoLocation}"/>
<TextBlock Text="{Binding Path=FormattedTimeStamp}"/>
</StackPanel>
</Grid>
The image is placing fine. But I cannot able to see the geo location. i think it takes only 100 width based on the image so it does not appears. But i want to place the image to left. and geo location below the image to right. Can any one please help me to find the solution.. this grid is the content of the data template just for more information.

As #coder is saying you should probably just change the code to:
<Grid Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinitionsHeight="*"/>
<ColumnDefinitionsHeight="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
...
</StackPanel>
<StackPanel HorizontalAlignment="Right" Grid.Column="1">
...
</StackPanel>

Related

UWP: Cannot make ListView scrollable

I have a page with a simple grid (2x2). In one grid on the bottom left corner is another Grid and inside this grid is a ListView bound to a collection. Entries can be added to the collection so the ListView grows in height (height of ListView is set to auto, so that all space available is used).
What I want is, if all available space (from the screen height) is used, scrollbars for the ListView should appear and should be usable. Funny (unfunny) thing is: scrollbars do appear but I cannot use them, I cannot scroll the ListView with the vertical scrollbar that appears when I hover the ListView.
It works, when I set the height of the ListView to a fixed value, but I don't want it that way, because then it doesn't use all the available space on the screen.
This is the XAML of the page (I removed some parts for demonstration purposes) :
<Page
x:Class="Qooli.TimeTracker.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Qooli.TimeTracker"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
...
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Name="spAddEntry" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="30">
<TextBlock Text="Add new entry:" Name="lblAddNewEntry" />
...
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="30">
<TextBlock Text="Allocated time:" Name="lblAllocatedTime" />
...
</StackPanel>
<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Margin="30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Daily overview:" Name="lblDailyOverview" Grid.Row="0" Grid.Column="0" />
<ListView Name="lvTimeEntries" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left"
Height="Auto"
MinHeight="100"
VerticalAlignment="Top"
MinWidth="300"
SelectionMode="Single"
ItemsSource="{x:Bind ViewModel.TimeEntriesAdvancedCollectionView, Mode=OneWay}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollMode="Enabled">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:TimeEntry">
<Grid Background="{Binding Type, Converter={StaticResource TimeEntryTypeColorConverter}}" Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="200"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind Time, Mode=OneWay}" Style="{StaticResource TitleTextBlockStyle}"
MinWidth="60"
MaxWidth="60"
Grid.Row="0" Grid.Column="0">
</TextBlock>
<TextBlock Text="{x:Bind Title, Mode=OneWay}" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"
MinWidth="100"
MaxWidth="100"
Grid.Row="0" Grid.Column="1">
</TextBlock>
<Button Name="btnEditTimeEntry" Grid.Row="0" Grid.Column="2" Margin="5,5,5,5">
<SymbolIcon x:Name="edit" Symbol="Edit"/>
</Button>
<Button Name="btnDeleteTimeEntry" Grid.Row="0" Grid.Column="3" Margin="5,5,5,5">
<SymbolIcon x:Name="delete" Symbol="Delete"/>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</Grid>
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="30">
<TextBlock Style="{StaticResource summaryTextStyle}" Text="Start time:" Name="lblDayStartTime" />
...
</StackPanel>
</Grid>
</Page>
Can someone spot why it is behaving this way?
You need to set the height of the second row to "*" for both grids.

Is it possible to have a VariableSizedGridView with virtualization?

I am creating a Windows Phone 8.1 (WinRT) application. The mainpage template is a two GridView (2 grids per row) and the height of grid varies (one item might occupy one row and other might occupy two rows). The design is similar to the pinterest app (pin.it) except the varying height in pinterest app. I was able to achieve it using VariableSizedGridView and I did lazy loading as well. But I could find that there is no virtualization because of which the memory goes on increasing on scrolling down. Can you suggest me the how to achieve variable sized grid with virtualization like the pinterest app?
Please check the code below:
<local:VariableSizedGridView x:Name="samples"
ItemsSource="{Binding listofData}"
Margin="0,0,-24,0">
<local:VariableSizedGridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid ItemHeight="190"
ItemWidth="{Binding Converter={StaticResource ScreenWidthMultiplier}, ConverterParameter=1}"
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</local:VariableSizedGridView.ItemsPanel>
<local:VariableSizedGridView.ItemTemplate>
<DataTemplate>
<Grid>
<local:MainPageTemplateSelector Content="{Binding}">
<local:MainPageTemplateSelector.BigTemplate>
<DataTemplate>
<Grid Height="380" Background="White"
Margin="0,3,6,3">
<Grid Margin="12" Background="Pink">
<Grid.RowDefinitions>
<RowDefinition Height="250"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Source="{Binding ImagePath}"
Stretch="Fill"/>
<Grid Grid.Row="1" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}" Foreground="Red"
Margin="12 3 12 5"/>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</local:MainPageTemplateSelector.BigTemplate>
<local:MainPageTemplateSelector.SmallTemplate>
<DataTemplate>
<Grid Height="190" Width="{Binding Converter={StaticResource ScreenWidthMultiplier}, ConverterParameter=1}"
Background="Blue" Margin="0,3,6,3">
<Grid Margin="12" Background="Green">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition />
</Grid.RowDefinitions>
<Image Height="150"
Stretch="Fill"
Source="{Binding ImagePath}"/>
<Grid Grid.Row="1" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Foreground="Red"
Text="{Binding Name}"
TextWrapping="Wrap"
Margin="12 5 12 5"/>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</local:MainPageTemplateSelector.SmallTemplate>
</local:MainPageTemplateSelector>
</Grid>
</DataTemplate>
</local:VariableSizedGridView.ItemTemplate>
</local:VariableSizedGridView>
And the VariableSizedGridView
public class VariableSizedGridView : GridView
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
dynamic model = item;
try
{
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, model.ColSpan);
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, model.RowSpan);
}
catch
{
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, 1);
element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, 1);
}
finally
{
element.SetValue(VerticalContentAlignmentProperty, VerticalAlignment.Stretch);
element.SetValue(HorizontalContentAlignmentProperty, HorizontalAlignment.Stretch);
base.PrepareContainerForItemOverride(element, item);
}
}
Thank you,
Neenu

Dynamically switch control type to show different content types

In my app (windows 8.1) I use the split Visual Studio template. It is working and I can show text content if I choose an item.
The content is mixed with text, images, pdfs.
So how can I dynamically switch the control type (eg TextBlock, Image, UserControl) based an the content data?
If I get text it should displayed in an TextBlock, but if I get an Image (Link) it should displayed in a image control. (Maybe the way to switch the control type is wrong, I don't know!?)
Can I solve this in XAML or should I do it in code behind?
I don't know how can I do this. Can anyone please give me a hint?
<Grid x:Name="itemDetailGrid" Margin="0,60,0,50">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImagePath}" Grid.Row="1" Margin="0,0,20,0" Width="180" Height="180" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
<StackPanel x:Name="itemDetailTitlePanel" Grid.Row="1" Grid.Column="1">
<TextBlock x:Name="itemTitle" Margin="0,-10,0,0" Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}"/>
<TextBlock x:Name="itemSubtitle" Margin="0,0,0,20" Text="{Binding Subtitle}" Style="{StaticResource SubtitleTextBlockStyle}"/>
</StackPanel>
<!-- <TextBlock Grid.Row="2" Grid.ColumnSpan="2" Margin="0,20,0,0" Text="{Binding Content}" Style="{StaticResource BodyTextBlockStyle}"/> -->
<Image Source="{Binding Content}" Grid.ColumnSpan="2" Grid.Row="2" Margin="0,20,0,0" Stretch="UniformToFill" />
The answer to your question is for you to use DataTemplates to define how each data type should be rendered in the UI. All you need to do is to declare a DataTemplate for each different data type:
<DataTemplate DataType="{x:Type System:String}">
<TextBlock Text="{Binding}">
</DataTemplate>
...
<DataTemplate DataType="{x:Type Custom:DataObject}">
<UserControl DataContext="{Binding}">
</DataTemplate>
If you omit the x:Key references (as in the example above), then the Framework will automatically render the content of the relevant DataTemplate whenever it comes across one of the specified data types. Please see the Data Templating Overview page on MSDN for further details.

How to scroll the enitre Windows Phone page with webbrowser content?

I have a webbrowser in my page, with other controls, I simply just want to scroll the entire page, instead of only scrolling the webbrowser. how can I do this?
my code:
<ScrollViewer >
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<convertstring:htmlconverter x:Name="htmlconv"/>
<convertstring:DateTimeToStringConverter x:Name="datetimestringconverter"/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="200"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="/Images/smallerheading.png"
Margin="0,0,10,0"
Grid.Column="1"/>
<TextBlock Text="Stuff"
Foreground="Black"
FontSize="45"
Margin="15,5,0,0"
/>
<Image Grid.Row="1" Grid.ColumnSpan="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
x:Name="img"/>
<TextBlock Grid.Row="2"
x:Name="txtTitle"
TextWrapping="Wrap"
Grid.ColumnSpan="2"
FontSize="30"
Foreground="Black" />
<StackPanel Grid.Row="3">
<TextBlock Grid.Column="0"
x:Name="Autho"
TextWrapping="Wrap"
Foreground="Black"/>
<TextBlock
Foreground="Black"
x:Name="txtDate"/>
</StackPanel>
<phone:WebBrowser x:Name="webbrowsercontrol"
Grid.Row="4"
Background="Transparent"
Foreground="Black"
Grid.ColumnSpan="2"
FontSize="20">
</phone:WebBrowser>
</Grid>
</ScrollViewer>
If you don't want to scroll the WebBrowser at all, you can draw a Border that is almost transparent (like #01000000).
That way, your touch movements will not be handled by the WebBrowser, but by the Border and the page will scroll instead of the WebBrowser content.

WPF problem: Need to draw a control on top of another

I've a shell window constructed of an Header, Main Content and Footer.
The main content is a tab control.
According to the design, one of the tab items content (a user control) needs to expand a little bit over the footer.
At first I thought about implmenting this with a negative Margin, but the footer no matter what I did always get drawn on top of my content.
For example consider the following xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
</Grid.RowDefinitions>
<StackPanel Background="Blue" Grid.Row="0"/> <!-- Header -->
<StackPanel Background="Red" Grid.Row="2"/> <!-- Footer -->
<TabControl Grid.Row="1" > <!-- Content -->
<TabItem>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Background="Yellow" >
<Button Width="100" Height="50" Content="Text" />
</StackPanel>
</Grid>
</TabItem>
</TabControl>
What I would want to achieve is making the Yellow StackPanel to reach the bottom of the screen somewhow, overlapping on top of the red footer.
Hope it is understandable.
Thanks
Ariel
Try this code sample:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
<RowDefinition Height="33*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="33*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.ColumnSpan="3" Background="Blue" Grid.Row="0"/> <!-- Header -->
<StackPanel Grid.ColumnSpan="3" Background="Red" Grid.Row="2"/> <!-- Footer -->
<TabControl Grid.ColumnSpan="3" Grid.Row="1"> <!-- Content -->
<TabItem>
<Grid>
<Button Width="100" Grid.Column="1" Height="50" Content="Text" />
</Grid>
</TabItem>
</TabControl>
<StackPanel Grid.Column="1" Grid.Row="3" Background="Yellow" />
</Grid>
The problem is that you want the stackpanel contained within the tab control, but you want it to extend beyond the bottom of the tab control. This isn't supported by the tab control.
No doubt TabControl is the problem. Maybe try to write your own TabControl.
Cheers.

Categories