How to change the item template of list box depending upon the Current Orientation in metro app? - xaml

Hi I am developing an metro app , my app works perfectly fine in landscape mode but now i want to make it compatible to Portrait mode also.
This is how i have defined students listbox :-
<ListBox x:Name="lstbxbStudents" Background="Transparent" Height="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="lstbxbStudents_SelectionChanged_1" HorizontalAlignment="Left" Width="Auto" Margin="4,50,0,122" Style="{StaticResource ListBoxStyle1}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="100" Orientation="Horizontal">
<TextBlock Text="{Binding stunum}" VerticalAlignment="Center" HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Width="450">
<TextBlock Text="{Binding studsc}" HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Orientation="Horizontal" Width="180">
<StackPanel>
<TextBlock Width="50" Text="{Binding stu_cod}" x:Name="txtblkstucode" HorizontalAlignment="Right" />
</StackPanel>
</StackPanel>
<StackPanel Width="150">
<TextBlock Text="{Binding stuby_prc}" VerticalAlignment="Center" TextAlignment="Right" HorizontalAlignment="Center" />
</StackPanel>
<StackPanel Width="100">
<TextBlock Text="{Binding stuqty, Mode=TwoWay}" TextAlignment="Center" x:Name="txtbxbqty" Tag="{Binding stunum}" VerticalAlignment="Center" HorizontalAlignment="Right" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now my doubt is when i rotate it to Portrait mode from landscape mode , since the width of the textblocks present inside the itemtemplate of listbox is already defined , when i rotate the it to Portrait, i am not able to see all the data present (it cuts off) since the width of the Portrait mode is less when compared to landscape mode.
1)Can i have two item templates for same listbox and switch between those two templates depending upon current orientation ??
2)How can i decrease/increase the width of the textblock present inside a item template of a listbox in runtime codebehind when the orentation changed event is fired.??
3)will visual states be useful at this point , if so then how ??
4)is there any other way of which i can solve the problem , am i missing any alternatives ??
Please help me out , Thanks in advance.

You can change the ItemTemplate using visual states. First put both of your item templates in resources:
<Page.Resources>
<DataTemplate x.Key="Landscape">
<!-- your landscape template -->
</DataTemplate>
<DataTemplate x.Key="Portrait">
<!-- your portrait template -->
</DataTemplate>
</Page.Resources>
Initially assign the landscape template to ListBox:
<ListBox x:Name="listbox" ItemTemplate="{StaticResource Landscape}" />
In VisualStateManager change the template for FullScreenPortrait visual state:
<VisualStateManager.VisualStateGroups>
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="listbox" Storyboard.TargetProperty="ItemTemplate">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Portrait}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateManager.VisualStateGroups>
Make sure you are using LayoutAwarePage as the base class for your page to make this work.

Related

UWP border wont use maximum space

Here I am again...
I have a ListView which loads items and prints them in the screen.
Everything is fine except I can't really make the XAML to work as I want it to.
The ListView outputs the content according to the DataTemplate which is supposed to output a "chat-like" display.
<DataTemplate x:Key="MessageListDataTemplate" x:DataType="disc:IMessage">
<Border Background="#2C2F33" BorderThickness="0,1,0,1" BorderBrush="Transparent" CornerRadius="5">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="5,2,0,0">
<TextBlock TextAlignment="Left" Text="{x:Bind Author,Mode=OneWay}" Foreground="White" FontSize="14"/>
<TextBlock TextAlignment="Left" Margin="5,3,0,0" Text="{x:Bind Timestamp,Mode=OneWay,Converter={StaticResource TimeToStringConverter}}" Foreground="LightGray" FontSize="10"/>
</StackPanel>
<TextBlock TextAlignment="Left" Margin="10,2,0,0" TextWrapping="WrapWholeWords" Text="{x:Bind Content, Mode=OneWay}" Foreground="#99AAB5" FontSize="20" />
</StackPanel>
</Border>
</DataTemplate>
The code is functional and it outputs this:
Instead of having the board to be sized according to the size of the message I would like it to be equal to the size of the screen. I have tried everything I know. Thank you!
Try adding the following style for the ListView:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>

Adaptive rendering of ListView items for UWP app

I'm writing a UWP app and have several areas where searches are performed and results are rendered in a ListView where the ItemTemplate is defined inside a DataTemplate. Nothing fancy is going on here - just returns a list of items in a single "column", if you will.
There are three supported screen states (or widths), 320, 640, and 1024. I'd like to render these search results in two "columns" when the screen state is 640 or 1024 (wide states).
I'd like to use adaptive triggers for this task, but I'm at a loss of how to do this intelligently. There are examples of creating different views for each device family, but they seem too dependent on checking the device family. Best practices dictate using screen width thresholds instead. Either way, it seems this could easily be accomplished using adaptive triggers.
Any insight or examples of where this is done would be appreciated. The code is included to provide more context and to act as my starting point.
<Page.Resources>
<ResourceDictionary>
<Style x:Key="TextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource LargeTextBlockStyle}">
<Setter Property="Foreground" Value="{StaticResource TitleBrush}" />
</Style>
<DataTemplate x:Key="SearchResult">
<StackPanel Width="{Binding ActualWidth, ElementName=Parent}">
<Border Background="Gray" MinWidth="235">
<Grid Height="155">
<Image Source="{Binding SearchResultImage}"
Style="{StaticResource ImageStyle}" />
<Rectangle Fill="{StaticResource BackgroundBrush}" />
<StackPanel Margin="10,10,15,10" VerticalAlignment="Center">
<TextBlock Text="{Binding SearchResultName}"
Style="{StaticResource TextBlockStyle}"
VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
<Button Style="{StaticResource ButtonStyle}"
Command="{Binding ViewRecipeCommand, Source={StaticResource Locator}}"
CommandParameter="{Binding}">
<StackPanel Margin="0" Orientation="Horizontal" HorizontalAlignment="Center">
<SymbolIcon Symbol="Calendar" Margin="0,0,10,0" />
<TextBlock x:Uid="ViewRecipeCommandTextBlock"
Text="View Recipe"
Style="{StaticResource TextBlockStyle}" />
</StackPanel>
</Button>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderStackPanel" Grid.Row="0" Margin="10">
<TextBlock x:Uid="RecipesTitle" Text="All Recipes"
Style="{StaticResource TextBlockStyle}"
Margin="0,0,0,10" />
</StackPanel>
<ListView x:Name="ResultsListView" Grid.Row="2"
ItemsSource="{Binding AllRecipes}"
ItemTemplate="{StaticResource SearchResult}" />
</Grid>
What I'd do to use a GridView instead a ListView, and change the GridView's ItemsPanel based on the width changes.
By using a GridView with an item width as wide as the screen size (320) you can get it to behave like a ListView, and if the GridView get's wider the content will automatically produce two columns for you. The only thing not to forget is to change the default scrolling direction of the ItemsPanel from horizontal to vertical.

GridView with two columns Win Phone 8.1

I am currently learning Windows Phone 8.1 app development. I am going through this Channel 9 series of video tutorials. They are useful but unfortunately are for Windows Phone 8, not 8.1 and so there are some things I can't follow. I am stuck in such a situation.
I want to have the following layout driven by some data:
So far I have the following code:
<Pivot x:Uid="Pvt">
<PivotItem Header="{Binding Animals.Title}">
<GridView ItemsSource="{Binding Animals.Items}">
<GridView.ItemTemplate>
<DataTemplate>
<!-- not sure what would go in here -->
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</PivotItem>
</Pivot>
But not sure what element I'm supposed to have in the <DataTemplate>!
Gridview works fine in Windows Phone apps. Here is code from one of my apps in the app store. You need to set the size of the outer most 'Grid' of the DataTemplate. You won't be able to get the grids to fit the screen exactly unless you do some dynamic sizing after the UI is loaded.
<GridView Grid.Row="2" Margin="0,0,0,0"
ItemsSource="{Binding InfoTypeList}"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="GridView_ItemClick">
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="120" Height="120">
<Border Background="{ThemeResource PhoneAccentBrush}">
<Image Source="{Binding ImagePath}" Stretch="Uniform" Margin="10,10,10,20"/>
</Border>
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="{Binding Name}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource BaseTextBlockStyle}" FontSize="18" HorizontalAlignment="Center" FontWeight="SemiBold" IsTextScaleFactorEnabled="False"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<Setter Property="Margin" Value="20 20 0 0"/>
</Style>
</GridView.ItemContainerStyle>
</GridView>
EDIT:
I played around with it and you can get it to look more like your picture (fit the items to the screen) by wrapping your GridView in a Viewbox and then limiting the number of rows by adding this to your GridView:
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical" MaximumRowsOrColumns="2" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
You will have to play around with your margins to get the correct spacing.

How to remove "focused" border from XAML listbox?

This problem is about the listbox itself and not it's cells. If I put listbox into a viewbox, and click on an item, the whole listbox will be surrounded with a 1px border. I do not want that, because it is ugly. How to remove this border?
Details:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Viewbox Grid.Row="1" Stretch="Uniform">
<StackPanel Orientation="Horizontal" Margin="0,20,0,20">
<Grid Width="200">
<ListBox ItemsSource="{Binding Rajzelemek}" Background="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ContentControl Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Content="{Binding Ikonja}" Width="25" Height="25" VerticalAlignment="Center" />
<TextBlock Text="{Binding}" VerticalAlignment="Center" Foreground="{ThemeResource ApplicationForegroundThemeBrush}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</StackPanel>
</Viewbox>
</Grid>
If I comment the <Viewbox Grid.Row.... part, everything is fine, but not scaled. I want stuff to get scaled, well that is why I use the viewbox, but I do not want this border:
The code above was put on a metro BlankPage1 too, and made the same thing.
I think you're looking for what's in the ListBoxItem template wherein there's a Rectangle acting as a Focus Visual, if you check out the default template you'll see it with a default brush attributed to it (FocusVisualWhiteStrokeThemeBrush) which you could either change in the template, or provide your own resource for it to find before it hits the default dictionaries like;
<SolidColorBrush x:Key="FocusVisualWhiteStrokeThemeBrush" Color="Transparent" />
Hope this helps.
EDIT
Sorry I was going by the picture you have, thought it was the item. In any case since your ViewBox is the culprit you just need to interact with the Border control within it >like you showed in a previous post of your own< where you're the one making that border. Something like;
<Viewbox>
<Viewbox.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</Viewbox.Resources>
...
</ViewBox>

ListViewItem won't stretch to the width of a ListView

I'm currently designing a windows 8 store app using XAML but I have a minor sizing issue. I have a ListView with a DataTemple.
The code for my ListView & DataTemplate are below:
<ListView x:Name="listPageItems"
Grid.Row="1"
SelectionMode="Extended"
IsSwipeEnabled="False"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource items}}"
ItemTemplate="{StaticResource NavigationItemTemplate}"
ScrollViewer.VerticalScrollBarVisibility="Visible">
</ListView>
<DataTemplate x:Key="NavigationItemTemplate">
<Grid Height="75">
<Grid.RowDefinitions>
<RowDefinition Height="1.6*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Fill="White" />
<Rectangle Fill="{StaticResource SSEGreenBrush}"
Grid.Row="1" />
<Border BorderThickness="2"
BorderBrush="{StaticResource SSEGreenBrush}"
Grid.RowSpan="2" />
<TextBlock x:Name="textTitle"
Text="{Binding ClientName}"
Style="{StaticResource TitleTextStyle}"
Foreground="{StaticResource SSEBlueBrush}"
Margin="10,5,5,5" />
<StackPanel Orientation="Horizontal"
Grid.Row="1"
HorizontalAlignment="Stretch">
<TextBlock Text="Last Edit :"
Style="{StaticResource SubtitleTextStyle}"
Foreground="{StaticResource SSEBlueBrush}"
Margin="3,0,0,3"
VerticalAlignment="Center" />
<TextBlock Text="SurveyDate"
Style="{StaticResource SubtitleTextStyle}"
Foreground="{StaticResource SSEBlueBrush}"
Margin="3,0,0,3"
VerticalAlignment="Center" />
</StackPanel>
</Grid>
</DataTemplate>
The listview is within a grid column with a fixed width of 240.
When the view is displayed the ListViewItems don't stretch to the width of the ListView. I've tried setting numerous properties including the HorizontalContentAlignment but I can't seem to get the ListViewItem to stretch!
Can anybody help?
I'm using Visual studio 2012, C# 4.5 and developing a Windows store app.
Try adding the following to your ListView definition
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
The easiest thing to do is just adding HorizontalContentAlignment="Stretch" to the ListView. There normally is no need for anything more.