Get SelectedItem from a nested RepeaterView - xaml

I am using DottorPagliaccius repeater view thats nested inside another repeaterview. The command RSSFeedSelectedCommand doesnt work unless on top repeater, which in theory makes sense but how can i get it to work?
I have looked into using Converters and bindtoeventcommand but cant see to get them working.
<repeater:RepeaterView x:Name="MainRepeater" SeparatorHeight="25" ItemsSource={Binding Feeds}">
<repeater:RepeaterView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Spacing="10">
<Label Text="{Binding Title}" TextColor="Blue" />
<Label Text="{Binding Description}" TextColor="Red" FontSize="12" />
<repeater:RepeaterView x:Name="MainRepeater2" EmptyText="No elements" ShowSeparator="true" SeparatorHeight="2" SeparatorColor="Silver" ItemsSource="{Binding Items}" SelectedItemCommand="{Binding RSSFeedSelectedCommand}">
<repeater`enter code here`:RepeaterView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Image Source="{Binding Image.Url}"></Image>
<StackLayout Orientation="Vertical">
<Label Text="{Binding Title}" TextColor="Black" />
<Label Text="{Binding Description}" TextColor="Black" FontSize="12" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</repeater:RepeaterView.ItemTemplate>
</repeater:RepeaterView>
</StackLayout>
</ViewCell>
</DataTemplate>
</repeater:RepeaterView.ItemTemplate>
</repeater:RepeaterView>

The Repeater was trying to find the command in Feeds however exists in the ViewModel.
<repeater:RepeaterView x:Name="MainRepeater2" EmptyText="No elements" ShowSeparator="true" SeparatorHeight="2" SeparatorColor="Silver" ItemsSource="{Binding Items}" SelectedItemCommand="{Binding Source={x:Reference RSSPage}, Path=BindingContext.RSSFeedSelectedCommand}">
and you have to name the page:
<ContentPage x:Name="PageName" />

If my assumption is correct, your class structure should be something like,
ViewModel
|__List of Feeds
|__List of Items
|__RSSFeedSelectedCommand
So, DataContext of your inner repeater control (MainRepeater2) will be Feed. So, try with DataContext of outer repeater control. Like,
<repeater:RepeaterView x:Name="MainRepeater2" ItemsSource="{Binding Items}"
SelectedItemCommand="{Binding DataContext.RSSFeedSelectedCommand,
ElementName=MainRepeater}"/>
For Xamarin:
<repeater:RepeaterView x:Name="MainRepeater2" ItemsSource="{Binding Items}"
SelectedItemCommand="{Binding DataContext.RSSFeedSelectedCommand,
Source={x:Reference MainRepeater}}"/>

Related

Conditional text in Xamarin Forms

How do I conditionally render a particular text in Xamarin Forms 5?
For example, I get some data from my API backend for a vendor and there may be an address in the database for this vendor or not.
If I do have vendor's address, I'd like to display it and if I don't have an address, I'd like to display something like "n/a".
Is there a way to handle this in the XAML page or do I have to handle it in code behind?
UPDATE:
Here's what the XAML page for the phone numbers ListView looks like:
<Grid Grid.Row="1" Grid.Column="0" RowDefinitions="150, *" ColumnDefinitions="250, 250">
<StackLayout
Grid.Row="0"
Grid.Column="0"
Padding="10">
<ListView
BackgroundColor="Transparent"
SeparatorVisibility="None"
ItemsSource="{Binding Contact.PhoneNumbers, TargetNullValue='n/a'}">
<ListView.Header>
<StackLayout>
<Label Text="Phone Number(s)"
FontAttributes="Bold"/>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding PhoneNumberDisplay}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</Grid>
You can use xaml binding with TargetNullValue
<Label Text="{Binding Location, TargetNullValue='n/a'}"/>
If you don't have an address your API or your code should set Location to null in order for TargetNullValue to work.
Update (reply to this comment).
Use TargetNullValue in the bindings inside ItemTemplate (applies to each single element) and not on itemsource binding:
<Grid Grid.Row="1" Grid.Column="0" RowDefinitions="150, *" ColumnDefinitions="250, 250">
<StackLayout
Grid.Row="0"
Grid.Column="0"
Padding="10">
<ListView
BackgroundColor="Transparent"
SeparatorVisibility="None"
ItemsSource="{Binding Contact.PhoneNumbers}">
<ListView.Header>
<StackLayout>
<Label Text="Phone Number(s)"
FontAttributes="Bold"/>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding PhoneNumberDisplay, TargetNullValue='n/a'}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</Grid>

Keep ListView.Header anchored/sticky/frozen to top when scrolling

How to keep the built-in Header of a ListView frozen to the top when scrolling vertically down through the ListView items?
Before flagging as duplicate: I tried to apply answers in Keep ListView.HeaderTemplate visible/static/sticky in UWP for Xamarin.Forms targeting Android without success.
Short code sample:
<ListView ItemsSource="{Binding MyList}"
HasUnevenRows="True"
SeparatorVisibility="Default"
CachingStrategy="RecycleElement">
<ListView.Header>
<Label HorizontalTextAlignment="Center"
FontAttributes="Bold"
Text="Header Title"/>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Name}"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is an alternative approach to this if the list isn't long
<StackLayout>
<Label HorizontalTextAlignment="Center"
FontAttributes="Bold"
Text="Header Title"/>
<StackLayout BindableLayout.ItemsSource="{Binding MyList}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<!-- boxview as separator -->
<BoxView HeightRequest="1" Color="Aqua" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>

Xamarin XAML file wont change after changing some code

In my XAML File after changing some code inside it and then debug on my phone, the changes I made do not reflect on my phone. It keep showing my old code.
Old code :
<ListView
ItemsSource="{Binding Allgroups}"
RowHeight="75"
IsGroupingEnabled="true">
<ListView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding NameNative}"></Label>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding TitleWithItemCount}" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
</ListView>
new code :
<Label Text="HELOO WORLD "></Label>
I Noticed every time i run the code , it keep showing the list.I have to click the save button then the list disappear and hello world appear .
I reset VS settings and relaunched it .
worked for me
<CollectionView ItemsSource="{Binding Categoriesxx}" IsGrouped="True">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="1" VerticalItemSpacing="5" HorizontalItemSpacing="5"></GridItemsLayout>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout >
<Label Text="{Binding NameNative}"></Label>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout BackgroundColor="AliceBlue">
<Label Text="{Binding Name}" FontSize="Title"></Label>
<Button Image="{Binding StateIcon}"
BackgroundColor="Transparent"
BorderColor="Transparent"
BorderWidth="0"
Command="{Binding BindingContext.ExpandCommand ,Source={x:Reference ServiceListPage}}"/>
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
</CollectionView>

Xamarin two labels in each end in one line

I have implemented a listview and in each item I want to have two labels, in each end horizontally. But in reality it just put the two labels next to eachother left aligned.
I read that maybe this is not possible with a stacklayout, as it doesn't take up more space than needed. (Even tried fill and fillandExpand which didn't help.)
Instead I should use a grid. But I have options on my listview, as grouping, refresh, caching, tapped, which I guess I don't have on a grid?
I would like to succeed with a listview if that is possible. Anyone have some insights to this layout issue?
Here is my xaml code:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Page.ItemsTest">
<ListView x:Name="ItemView"
ItemsSource="{Binding ItemGroup}"
CachingStrategy="RecycleElement"
IsGroupingEnabled="true"
HasUnevenRows="True"
ItemTapped="Handle_ItemTapped">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#FFA500" Orientation="Vertical" Padding="10">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Heading}" TextColor="White" FontAttributes="Bold" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="10" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Name}" FontAttributes="Bold" HorizontalTextAlignment="Start"/>
<Label Text="{Binding Start, StringFormat='{0:HH:mm}'}" FontAttributes="Bold" HorizontalTextAlignment="End"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
Central part is this:
<StackLayout Orientation="Horizontal" Padding="10" HorizontalOptions="FillAndExpand">
<Label Text="{Binding Name}" FontAttributes="Bold" HorizontalTextAlignment="Start"/>
<Label Text="{Binding Start, StringFormat='{0:HH:mm}'}" FontAttributes="Bold" HorizontalTextAlignment="End"/>
</StackLayout>
Update:
As requested I have a colored the background of the two labels and the stacklayout. It's the same output if I use HorizontalOptions="End" and HorizontalTextAlignment="End" at the same time or each one alone. Also if I remove the HorizontalOptions="FillAndExpand" on the stacklayout, it's still the exact same graphical output. (The orange color was already present)
Maybe you could use a Grid instead of the StackLayout and place each Label in a different Column:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="{Binding Name}" FontAttributes="Bold" HorizontalTextAlignment="Start"/>
<Label Grid.Column="1" Text="{Binding Start, StringFormat='{0:HH:mm}'}" FontAttributes="Bold" HorizontalTextAlignment="End"/>
</Grid>
You could also use nested StackLayout
<StackLayout>
<Label />
<Label Text="Gender:" FontAttributes="Bold"/>
<StackLayout Orientation="Horizontal">
<Label HorizontalOptions="Start" Text="First Name: " FontAttributes="Bold"/>
<Entry HorizontalOptions="EndAndExpand" Placeholder="First Name" MaxLength="256" Text="{Binding FirstName}"></Entry>
</StackLayout>
</StackLayout>

How to create list view with side count like mail

Am working small Xamarin.forms application.Now i have doubt to how to count and display list items in label
like email and gmail.
I'm browsing in google various sites i did't get result
My Xaml code is below how to display count in side bar and i used grid for that sum Xaml.task error will be occur
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:emit="clr-namespace:System.Reflection.Emit;assembly=mscorlib"
x:Class="vMonitor.Views.HomeListView"
Title="Home List View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<ScrollView>
<StackLayout Orientation="Vertical">
<ListView ItemsSource="{Binding Model}" Margin="20,0,20,0"
x:Name="listView"
SeparatorVisibility="Default" SeparatorColor="Brown"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<StackLayout Orientation="Horizontal" Padding="10">
<Label Text="{Binding Name}" FontSize="20" FontFamily="TimesNewRomen" FontAttributes="None">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TabCommand, Source={x:Reference listView}}" CommandParameter="{Binding .}"/>
</Label.GestureRecognizers>
</Label>
<Label Text="{Binding UserID}" FontSize="20" FontFamily="TimesNewRomen" FontAttributes="None"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ScrollView>
</ContentPage>
Then you can use ViewCell for List Item.
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,10" Orientation="Horizontal">
<Label
VerticalTextAlignment="Center"
Text="{Binding ItemName}" TextColor="#FF1654" FontAttributes="Bold" FontSize="16"/>
<Label VerticalOptions="End"
VerticalTextAlignment="Center"
Text="{Binding ItemCount}" TextColor="#FF1654" FontAttributes="Bold" FontSize="16"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
You can Bind ItemName and ItemCount. If you want to Display Left Side Image then you can add Image at start position in ViewCell.
For Expandable you have to use IsVisible Property for that cell.