Nested Grouped ListView in XAML - xaml

I'm making a chatting app like WhatsApp. This is the layout I want to make,
Me(Static HeaderText)
MyInformation(Profile Image and name)
Favorites(Static HeaderText)
My Favorite friend information(Profile Image and name)
My Favorite friend
Friends(Static HeaderText)
A
My friend information(His name starts with A)
My friend
B
My friend
I implemented this with 3 listviews(Me, favorites, friends) in the Grid.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<CollectionViewSource x:Name="CollectionGroupedView" IsSourceGrouped="True" ItemsPath="Members" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0" x:Name="MeView" SelectionMode="None"
ItemTemplate="{StaticResource StandardTripleLineItemTemplate}"
Header="Me"
>
</ListView>
<ListView Grid.Row="1" x:Name="FavoriteView" SelectionMode="None"
ItemTemplate="{StaticResource StandardTripleLineItemTemplate}"
Header="Favorite"
>
</ListView>
<ListView Grid.Row="2" x:Name="FriendListView" SelectionMode="None"
ItemsSource="{Binding Source={StaticResource CollectionGroupedView}}"
ItemTemplate="{StaticResource StandardTripleLineItemTemplate}"
Header="Friends"
>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</Grid>
And this is the result.
But as you can see, it doesn't work what I expected first.
The first problem is, each listview has its own ScrollView.
I need one outer scrollview. To solve this problem I tried to use StackPanel in the outside of listviews. But then scrollview has gone.
The second one is, when I scroll down the third listview, the header text Friends also scrolled. It shouldn't be.
If I can use nested CollectionViewSource, it might be possible. But I think there is no interfact like that.
How should I do layout this structure? Any experience or idea?
P.S Target Platform is Windows Phone 8.1. But I screen-captured it on WinRT application to show you the scrollbar.

1- for the whole scroll, one thought is that you can add your main grid in scrollview control in that case all the page will have one scroll.
here is how.
<ScrollViewer>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Resources>
<CollectionViewSource x:Name="CollectionGroupedView" IsSourceGrouped="True" ItemsPath="Members" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0" x:Name="MeView" SelectionMode="None"
ItemTemplate="{StaticResource StandardTripleLineItemTemplate}"
Header="Me"
>
</ListView> .... </Grid></ScrollViewer>

You could try this: http://winrtxamltoolkit.codeplex.com/
It has a control called TreeView. Maybe that will help!

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>

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.

How to fix Listview ScrollViewer scrolling in PivotItem changing

I have a ListView in PivotItem and my pivot contains 3 pivot items. Each Piovt Item contain ListView. I want to disable scrolling on all the ListViews while user changing the Pivot Item swiping left/right. Currently while swiping left/right the pivot item is in changing mode and also my ListView scrolls. I have tried ManipulationStarted and ManipulationCompleted events but it is not working? Is there a way to achieve this? What I want is the same behavior of WP 8.1 email app, while swiping left/right it disables listview view scrolling.
<Pivot Grid.Row="1">
<PivotItem Margin="0" >
<PivotItem.Header>
<TextBlock Text="web" />
</PivotItem.Header>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="19,0,19,15"
Style="{StaticResource PhoneAccentTextSmallStyle}"
Visibility="{Binding CountryFacetCurrentlyShowing,Converter={StaticResource empltyStringToVisibilityConverter}}"
Text="{Binding CountryFacetCurrentlyShowing}"></TextBlock>
<!-- Search List Items -->
<ListView Grid.Row="2" x:Name="grdSearchResults" Width="{Binding ElementName=searchView,Path=ActualWidth}" ItemsSource="{Binding SearchedMembers}"
Visibility="{Binding ElementName=btnGridView,Path=IsEnabled,Converter={StaticResource boolToVisibiliytConverter}}"
LayoutUpdated="grdSearchResults_LayoutUpdated"
SelectedItem="{Binding SelectedMember,Mode=TwoWay}"
SelectionMode="{Binding ListViewMode}"
ItemTemplate="{Binding ItemTemplate}"
ItemContainerStyle="{StaticResource ListViewItemStyle99}">
</ListView>
<!-- Search Grid Items -->
<GridView Grid.Row="2" x:Name="grdSearchResults1" Width="{Binding ElementName=searchView,Path=ActualWidth}" ItemsSource="{Binding SearchedMembers}"
Visibility="{Binding ElementName=btnListView,Path=IsEnabled,Converter={StaticResource boolToVisibiliytConverter}}"
Margin="13,0,13,0" SelectedItem="{Binding SelectedMember,Mode=TwoWay}"
LayoutUpdated="grdSearchResults_LayoutUpdated"
SelectionMode="{Binding ListViewMode}"
ItemContainerStyle="{StaticResource GridViewItemStyle99}"
ItemTemplate="{StaticResource SearchGridItemDataTemplate}">
<!--<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="{Binding DataContext.ItemWidth, Mode=OneWay, ElementName=searchView}"></Setter>
</Style>
</GridView.ItemContainerStyle>-->
</GridView>
<TextBlock Margin="19,10" Text="No matches found." FontSize="16" x:Name="lblNoConten" Foreground="DarkGray" Visibility="{Binding NoContentVisibility}"></TextBlock>
</Grid>
</PivotItem>
<PivotItem Margin="0">
<PivotItem.Header>
<TextBlock Text="local" />
</PivotItem.Header>
</PivotItem>
</Pivot>
Fixed this problem. I was using a default ListView style(which contains nothing new) in my resources and that was causing the problem after removing default style from my resources it works :). Do not know why it was causing the issue.

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.

Windows Phone Context Menu Item Text Not Appearing

I have a Windows Phone 8 app using XAML/C#. My app has an ItemsControl that relies on a data template. My DataTemplate looks like the following:
<DataTemplate x:Key="myTemplate">
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding DisplayName}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextLargeStyle}" TextTrimming="WordEllipsis" >
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem x:Name="customerMenuItem" Foreground="White" Header="View Customer Profile" Click="customerMenuItem_Click" Tag="{Binding Path=CustomerName}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
<TextBlock Text="{Binding Summary}" TextWrapping="NoWrap" Grid.Row="1" Style="{StaticResource PhoneTextSmallStyle}" />
</Grid>
<StackPanel Orientation="Horizontal" Grid.Column="1"><!-- Stuff here --></StackPanel>
</Grid>
</DataTemplate>
This DataTemplate is referenced in the main part of my XAML as shown here:
<Grid x:Name="ContentPanel" Grid.Row="1" Grid.ColumnSpan="2" Margin="12,0,12,0">
<ScrollViewer>
<ItemsControl x:Name="myItemsControl" ItemTemplate="{StaticResource myTemplate}" ItemsSource="{Binding Customers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</Grid>
Please note, the "toolkit" namespace comes from clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit. When I hold my finger (or mouse) on the TextBlock, a context menu appears. However, I never see the words "View Customer Profile". I just see a block box that represents the context menu itself. I know that the item is there though. I know because the customerMenuItem_Click event successfully fires. I have a MessageBox in there that shows the value of the Tag. That value is always correct. For some reason though the menu item text is not appearing. What am I doing wrong?
You put Foreground = "White". Context menu is on white background. That is why you don't see your menu item.