Focus control within DataTemplate of GridView - xaml

I have a GridView that uses a DataTemplate to provide a UI so users can manage subscriptions to a dataservice. The DataTemplate contains text and an image and also a Button and a ToggleButton. Using this on Mobile and Desktop the user can tap or click the buttons within the control. On Desktop you can even Tab inside the control and select the buttons. However on Xbox I am only able to focus on each DataTemplate item, I cannot get it to focus on the buttons inside, is there a way around this without enabling Mouse Mode on the Xbox?
<DataTemplate x:Key="DataTemplate1">
<Grid Background="#33FFFFFF">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="80" Source="{Binding TEAMID, Converter={StaticResource uriConverter}}" Grid.RowSpan="3"/>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding TEAMNAME}" VerticalAlignment="Top" Grid.Column="1"/>
<Button Content="Unsubscribe" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Tag="{Binding TEAMID}" Tapped="Button_Tapped"/>
<ToggleButton x:Name="subscribe_tb" Content="" HorizontalAlignment="Center" FontFamily="Segoe MDL2 Assets" Tag="{Binding TEAMID}" IsChecked="{Binding isPinned}" Grid.Row="3" Grid.Column="1" Unchecked="subscribe_tb_Unchecked" Checked="subscribe_tb_Checked"/>
</Grid>
</DataTemplate>

Solved by changing the Style of the GridView.ItemContainerStyle:
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="IsFocusEngagementEnabled" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>

Related

How to dynamically update ListView height while keeping the ScrollViewer enabled?

ListView is placed inside UserControl which is set in parent XAML to asterix "*" height.
I want to use ListView with possibility to scroll items, when there are items that exceed ListView. It should work for different size of window.
It works fine when I set Grid's RowDefinitions with fixed integer, but when I try to use asterix "*" ScrollViewer disables.
I also tried to bind and update RowDefinition's height via some code behind in overriden MeasureOverride method, but it didn't work as expected.
Here is code inside my UserControl:
<Grid x:Name="ContentArea"
Background="{StaticResource MixerBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="{x:Bind ListViewHeight}" />
</Grid.RowDefinitions>
<ListView
ItemsSource="{x:Bind ViewModel.Source,Mode=TwoWay}"
CanDragItems="True"
CanReorderItems="True"
AllowDrop="True"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:Track">
<Grid
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
BorderBrush="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBlock
Text="{x:Bind Id}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="24"
Margin="20,5,20,5"/>
<Grid
Background="Black"
Width="500"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1">
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I expect to get the ScrollViewer working correctly, but ListView stay at the old size or scroll bar is disabled - depending on Height value.
Is there any way to achieve dynamically resizing ListView with scroll?
Edit
Here is parent Page XAML code which is loaded into Frame via Light MVVM framework:
<Grid
x:Name="ContentArea">
<Grid
Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height="300" />
</Grid.RowDefinitions>
<maineditor:MainEditorMenuControl x:Name="ProjectMenu" />
<maineditor:MainEditorWorkspaceControl x:Name="Workspace" Grid.Row="1"/>
<maineditor:MainEditorMixerControl x:Name="Mixer" Grid.Row="2" />
</Grid>
</Grid>
Edit 2
I think the problem may be connected with MVVM template I've created with Windows Template Studio plugin for Visual Studio. If I try to recreate minimal solution from scratch with all properties 1:1 as in my app it works in fresh project, but not in mine.
How to dynamically update ListView height while keeping the ScrollViewer enabled?
If you want make RowDefinition height same as the ListView, you could give the ListView a name and use {Binding ElementName=MyListView,Path=ActualHeight}syntax to bind both height property.
<Grid x:Name="ContentArea">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=MyListView,Path=ActualHeight}" />
</Grid.RowDefinitions>
<ListView
Name="MyListView"
CanDragItems="True"
CanReorderItems="True"
AllowDrop="True"
Loaded="MyListView_Loaded"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.ItemTemplate>
<DataTemplate >
<Grid
Background="LightGray"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
BorderBrush="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBlock
Text="{Binding}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="24"
Margin="20,5,20,5"/>
<Grid
Background="Black"
Width="500"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1">
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

ListView gets not scrollable

I have a proble which seems pretty common and has been asked alot, but I can't find a fixing solution for my problem.
So I try to use 3 listviews in in one page all shall have a title and an explaining image, but instead of designing all 3 ListViews in one page I outsourced one listview with image and title into a control, which I use in my page.
The 3 Controls are placed in a grid. When the listview items get filled thy scrollbar should become visible if the remaining space is no longer enough but it won't show.
I provided a sandbox project where I placed the control and etc. like in the application I'm working on. SampleProject
Their you just need to press start and the listviews get filled. But they don't show the scrollbar.
Thanks in advance!
Edit 1:
As requested I share my code below. If you open up the sample project then you do not need to read further until a second edit is done.
Control containing listview:
<Grid>
<Grid x:Name="Section"
HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="grdTitleArea"
HorizontalAlignment="Stretch"
Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BitmapIcon
VerticalAlignment="Center"
HorizontalAlignment="Center"
Tapped="grdTitleArea_Tapped"
UriSource="ms-appx:///Assets/area.png"
Height="40" />
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Tapped="grdTitleArea_Tapped"
Text="Area"
Grid.Column="1" />
</Grid>
<!--<ScrollViewer
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
VerticalScrollMode="Enabled"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
HorizontalScrollBarVisibility="Hidden"
HorizontalScrollMode="Disabled"
>-->
<ListView x:Name="ListView"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Auto"
Grid.Row="1">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="1"
Margin="1"
Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ActionDescription}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--</ScrollViewer>-->
</Grid>
</Grid>
Control which contains the control above 3 times:
<Grid x:Name="ProgressControl">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:SynchronizeSettingsControl
Visibility="Visible"
x:Name="Settings" />
<local:SynchronizeSectionControl
x:Name="ActualAction"
Visibility="Visible"
Grid.Row="1" />
<local:SynchronizeSectionControl
x:Name="Error"
Visibility="Visible"
Grid.Row="2" />
<local:SynchronizeSectionControl
x:Name="Log"
Visibility="Visible"
Grid.Row="3" />
</Grid>
Page which contains the control which contains the listview:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
Text="Demo"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Width="70"
VerticalAlignment="Stretch"
Content="Useless Button" />
</Grid>
<Controls:SynchronizeControl
x:Name="ctlSync"
Grid.Row="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
<Button VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
x:Name="btnStart"
Content="Start"
Tapped="btnStart_Tapped"
Grid.Row="3" />
</Grid>
The problem is you used Auto height in the page. This means basically that the page tells the local:SynchronizeSectionControl control: "You can use whichever height you want".
The control then has * as the height of the second row which means "use the rest space available". But because the page offered essentially "infinite height", the ListView height will stretch as much as possible to accommodate for all its items and hence it doesn't scroll, as its height is big enough to display everything, although it is cut off and not visible, because the window height is of course limited.
The thing is you used the Auto property for the height of your rows in your control.
This works fine is the control you use uses a definite space. Like a button or similar stuff. But when the control can extend indefinitely the allocation for the space gets screwed up.
Basically the control displays at its maximum size but extends way over its boundaries.
You can prevent that when you use the * as a Height value.
This will lead to the control taking up all the space available. You can further limit this with using the MaxHeight property.
If you do it that way it will display a scrollviewer when necessary and it will even resize when you change the window size.

C# UWP - The first image inside ListView is incorrectly sized

I have a simple layout that basically displays a list of items in ListView using an ItemsWrapGrid as the panel template. The problem I am having is that the first image in the ListView is always bigger than the rest, even with a fixed width / height set. I am completely stumped.
An image of the problem:
The ListView XAML is:
<ListView ItemsSource="{Binding Currencies}" ItemTemplate="{StaticResource PortfolioCurrencyTemplate}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" Width="Auto" Height="Auto"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
The data template:
<Page.Resources>
<DataTemplate x:Key="PortfolioCurrencyTemplate" x:DataType="viewModels:PortfolioViewModel">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="2"
Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="1" MaxWidth="100" MaxHeight="100" Source="https://www.cryptocompare.com/media/19633/btc.png"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Name}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Symbol}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="2" Text="{Binding LastPrice}" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</Page.Resources>
Instead of using ListView and changing ItemsPanelTemplate to create a GridView Effect and tackle issues one by one, I would suggest you switch to AdaptiveGridView.
You can install Nuget Package for UWP Community Toolkit from Here
Add below namespace to your page
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
Now your ListView needs to be replaced like below.
<controls:AdaptiveGridView ItemsSource="{Binding Currencies}"
ItemTemplate="{StaticResource PortfolioCurrencyTemplate}"
DesiredWidth="250"/>
Output from Designer
Good Luck.

In Win10 application using two webview not able to see content if i dont give minHeight to control?

Below is the code snippet:-
In Below code I am Using two web view control and binding the HTML content by using custom property. Here I want that Web-view content should be displayed without any scroll and automatically fit to grid according to content size.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<ResourceDictionary>
<CollectionViewSource x:Name="HtmlSource"/>
</ResourceDictionary>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Background="#fffff0">
<TextBox x:Name="TxtHtmlInput" Width="800" TextWrapping="Wrap" HorizontalAlignment="Left" Height="250"></TextBox>
<Button Margin="10,0,0,0" x:Name="COnvert" HorizontalAlignment="Center" Content='HTML TO TEXT' Tapped="COnvert_Tapped"></Button>
</StackPanel>
<WebView Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Width="Auto" ScrollViewer.VerticalScrollMode="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" x:Name="customWebView" webViewer:MyExtensions.HTML="{Binding Source={StaticResource HtmlSource}, Path=HTML}">
</WebView>
<Grid Height="Auto" Grid.Row="2" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<WebView Height="Auto" Width="Auto" x:Name="customWebView1" webViewer:MyExtensions.HTML="{Binding Source={StaticResource HtmlSource}, Path=HTML}"></WebView>
</Grid>
</Grid>

Windows phone Horizontal Listbox image center-lock

I have a ListBox with images as items, I need each image to take the full width of the screen, and to be center-locked (like ViewPager in android)
this is what I have so far:
<Grid x:Name="ContentPanel" Grid.Row="1" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="1" ItemsSource="{Binding Zones[0].listBannieres}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding banniere}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
thank you.
SOLVED
<phone:PivotItem Header="Zone 1" Margin="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" VerticalAlignment="Bottom" >
<phone:Pivot ItemsSource="{Binding Zones[0].listBannieres}">
<phone:Pivot.HeaderTemplate>
<DataTemplate />
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemContainerStyle>
<Style TargetType="phone:PivotItem">
<Setter Property="Margin" Value="0"/>
</Style>
</phone:Pivot.ItemContainerStyle>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding banniere}"/>
</StackPanel>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
</StackPanel>
</Grid>
</phone:PivotItem>
I would recommend using Pivot as suggested in the comments or a Panorama control, if you place those inside another control, you can have them visible at the bottom only. Here is an example with pivot:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<phone:Pivot Grid.Row="1" ItemsSource="{Binding Images}" Margin="0">
<phone:Pivot.HeaderTemplate>
<DataTemplate></DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemContainerStyle>
<Style TargetType="phone:PivotItem">
<Setter Property="Margin" Value="0" />
</Style>
</phone:Pivot.ItemContainerStyle>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImagePath}" Stretch="Fill" />
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
</Grid>
Here only the bottom part is scrolled to as you wanted. It will also "snap" to the images when scrolling, which I also think the Android viewpager does. :)
If you instead change Pivot to Panorama and PivotItem to PanoramaItem you can get another nice result, where you see a small part of the next image. Here is an image of the result:
Edit: To remove the margin and headers, make sure you set the HeaderTemplate to an empty one and the Margin on PivotItem to 0. See the updated code above.