Empty view in list View in xamarin - c#

I have a list view in my xamarin app and I need to put an option that when the list is empty, in the collection view we have <CollectionView.EmptyView> but when I search for list view there is no option for it and it's more complex, so, there is a quick fix or not? and what is the there standard solution for it ?

Actually,CollectionView is a better choice for empty view.However, if you insist on using listivew to achieve empty view effect,you could use this package Syncfusion.Xamarin.SfListView.Just binding IsVisible property when the listview is empty like below,for more details please refer to this repo.
<Grid>
<Button x:Name="ItemSource" Grid.Row="0"
Text="Change ItemSource"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
Command="{Binding ChangeItemsSource}"/>
<Grid IsVisible="{Binding IsVisible}" Grid.Row="1">
<Label x:Name="label"
Text = "No Items :(" />
</Grid>
<sync:SfListView x:Name="listView" Grid.Row="1"
ItemsSource="{Binding ContactsInfo}"
IsVisible="{Binding Path=IsVisible, Converter={StaticResource visibilityConverter}}"
ItemSize="30">
<sync:SfListView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding ContactName}"/>
</DataTemplate>
</sync:SfListView.ItemTemplate>
</sync:SfListView>
</Grid>
Official reference link:https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/emptyview

Related

Change a button's image on tap of other button inside a list view, view cell

I have a listview. This list view has 5 rows with two buttons namely A & B. When I tap on button A on a row, I want to change the image on A as well as B on the same row and vice-versa. I am able to individually tap and change the image on the same button but don't know how to change the image on the other button. Here is my listview:
<ListView x:Name="GroupedView" SeparatorColor="Transparent" GroupDisplayBinding="{Binding Title}" IsGroupingEnabled="true" HasUnevenRows="true" >
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="5" BackgroundColor="#E2F5F9">
<Label Text="{Binding Title}" TextColor="{StaticResource NavyBlue}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Spacing="2" Padding="5">
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding QuestionName}" />
</StackLayout>
<StackLayout IsVisible="{Binding ShowYesNo}" Spacing="15" Orientation="Horizontal" HorizontalOptions="End">
<Button ClassId="Yes" Clicked="ChoiceSelected" CommandParameter="{Binding question_id}" Image="{Binding YesChoiceImg}" />
<Button ClassId="No" Clicked="ChoiceSelected" CommandParameter="{Binding question_id}" Image="{Binding NoChoiceImg}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I am then using the sender to identify the class ID and change the image of the button.
Should I be using a command? Should I be doing something else? Please help. Thanks
If you want to use the CommandParameter you should be using a Command. At the moment you're mixing 2 different ways to handle the click.
One thing to note though is that if you use a command you usually want to bind it to a Command that is defined on your ViewModel but since inside the DataTemplate your BindingContext is the ListView item instead of the ViewModel so you have to reference around that. Something like this should work:
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Spacing="2" Padding="5">
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding QuestionName}" />
</StackLayout>
<StackLayout IsVisible="{Binding ShowYesNo}" Spacing="15" Orientation="Horizontal" HorizontalOptions="End">
<Button ClassId="Yes" Command="{Binding Path=BindingContext.ButtonCommand, Source={x:Reference MyQuestionPage}}" CommandParameter="{Binding .} Image="{Binding YesChoiceImg}" />
<Button ClassId="No" Clicked="ChoiceSelected" CommandParameter="{Binding question_id}" Image="{Binding NoChoiceImg}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
Note here that you have to give your ContentPage an x:Name (so you can reference it and call the BindingContext on it). And the "{Binding .}" binds to the current list item. So no need to search for it on id you can just plug it into the command directly!

How to data bind a ListView item to an item in a structured list with multiple indexes?

I'm attempting to data bind a list of information to a ListView in Xamarin.forms, but I'm having issues because of how it is indexed. I need to get the string of information found in sortedList[0].Info[multiple indexes].CoverLink to display on my Image element inside of my Xamarin app, but I'm not sure how to go about it. My Xaml file is as follows:
<ListView RowHeight="100" x:Name="PinnedListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="Start">
<Image Source="{Binding CoverLink}" HeightRequest="100"/>
<StackLayout Orientation="Vertical">
<Label Text="{Binding ID}"/>
<Label Text="{Binding SomeOtherBinding}"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
and I'm assigning the ItemSource via c# by stating:
PinnedListView.ItemsSource = sortedList;
Here is a screenshot of my list architecture:
How to data bind it? Thanks.
you need to specify which element of the Info array you want to use
<Image Source="{Binding Info[0].CoverLink}" HeightRequest="100"/>
As you can see, the CoverLink is in the Infonested array, so, in order to access to it try this:
<Image Source="{Binding Info[0].CoverLink}" HeightRequest="100"/>

Adding a TapGestureRecognizer to a Xaml Grid - Doesn't work?

Xamarin Forms 2.5
I have a ListView with a custom GroupHeaderTemplate that renders nicely:
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<templates:SummaryCellHeader />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
The GroupHeaderTemplate has a Grid with a TapGestureRecognizer.
<Grid>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ListHeaderTappedCommand}" />
</Grid.GestureRecognizers>
</Grid>
The TapGestureRecognizer never fires. This template works if used outside a ListViewHeader.
Are TapGestureRecognizers allowed in a ListView GroupHeaderTemplate?
The issue is the binding context for the header is the data the list is showing, not the view model.
Give your list view a name then use that to change the binding context source for the command.
<ListView ItemsSource="{Binding ListOfPeople}"
IsGroupingEnabled="true"
x:Name="PersonList">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference PersonList}, BindingContext.ListHeaderTappedCommand}" />
</Grid.GestureRecognizers>
Thank you Steve Chadbourne. Seems you can also put a Command on the Key if the Key is a complex object rather than a simple string:
<Grid RowSpacing="0" >
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Key.ListHeaderTappedCommand}" />
</Grid.GestureRecognizers>
The benefit is that you get a reference to the Header POCO used to create the list. This is helpful to determine the action to take onHeaderClick

Bullets in a Xaml Tooltip

Everything is in the title. I'd like to be able to add some bullet list in a Tooltip but so far haven't found any simple way.
thanks in advance!
You want to use the BulletDecorator as part of the ToolTip. Example:
<ToolTip>
<BulletDecorator>
<BulletDecorator.Bullet>
<Ellipse Height="10" Width="10" Fill="Blue"/>
</BulletDecorator.Bullet>
<TextBlock>Text with a bullet!</TextBlock>
</BulletDecorator>
</ToolTip>
For more information, see http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.bulletdecorator(v=vs.100).aspx
you must have a custom tooltip for this
a nice blog example
http://stevenhollidge.blogspot.co.il/2012/04/custom-tooltip-and-popup.html
microsoft info
http://msdn.microsoft.com/en-us/library/ms745107.aspx
just put somekind of rich textbox or listbox in the content...
Just a guess:
Why don't use unicode characters (0x2981 for example) and \r\n for lie breaks?
I got it displaying correctly with the following:
<ListView
x:Name="listView"
Margin="0,-5,0,0"
BackgroundColor="Transparent"
HasUnevenRows="True"
HeightRequest="50"
HorizontalOptions="CenterAndExpand"
ItemsSource="{Binding TradingHoursList}"
SeparatorColor="Transparent">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<RelativeLayout>
<Label Text="•"/>
<Label
Margin="10,0,0,0"
FontAttributes="Italic"
FontFamily="Arial Black"
FontSize="15"
HorizontalOptions="Start"
Text="{Binding}"
VerticalOptions="Start"/>
</RelativeLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

How to use Nested Views in WPF MVVM

Hi I am trying to understand the best practise to use nested views.
I have an 'Attribute' View which is bound to collection of name value pairs in the view model. I need to reuse this at various places in my UI.
I have another 'Condition View' which has a string property and Dictionary(string,string) collection. I tried to create a text box and add the Attribute View control in the XAML
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="{x:Static l:StringResources.ConditionViewLabelText}" />
<TextBox Text="{Binding Type,Mode=TwoWay}" Width="100" />
</StackPanel>
<vw:AttributeView />
</StackPanel>
I want to bind the AttributeView's bound property to the Dictionary(string,string)'s collection property of the parent view model. Whats the best way to do it. I am not able to bind the vw:AttributeView to a ConditionViewModels ?
Can you please let me know the best practise to do this?
-- EDIT Please find my AttributeView (This is the child view's xaml code). The data template is bound to an observable collection on the AttributeViewModel
<StackPanel>
<ItemsControl ItemsSource="{Binding AllAttributes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Width="100" Text="{Binding Name, Mode=TwoWay}" Margin="5,0,5,0" />
<TextBox Width="100" Text="{Binding Value, Mode=TwoWay}" Margin="5,0,5,0" />
<TextBlock Width="100" Text="{Binding KeyValue, Mode=OneWay}" />
<Button Width="50" Content="{x:Static l:StringResources.AttributeViewButtonDeleteText}" Command="{Binding Path=DataContext.DeleteAttribute, ElementName=AttributeControl}" CommandParameter="{Binding Name}"></Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Name="btnSomething" Content="{x:Static l:StringResources.AttributeViewButtonAddText}" Command="{Binding AddNewAttribute}" />
</StackPanel>
</Grid>
Based on your comments that your parent / child relationship is not reflected in your view model, you have two options:
Create the relationship in your view model to reflect the relationship in your view, allowing you to navigate from the parent to the child and vice-versa should you need this.
Use a RelativeSource FindAncestor binding to navigate up the visual tree and locate a control bound to the parent view model, biding to this controls DataContext.
Option (2) will make you look clever, but option (1) is much simpler!

Categories