Reputation: 113
I have a problem with binding in Xamarin Forms. I want to set IsVisible
property of Label
to true/false
according of count items of Listview
. If Listview
have any items, Label IsVisible
will be false
, otherwise will be true
. Is it possible to make in Xamarin Forms with binding? I tried to do this but I don't know how to convert number 0
to boolean false
in XAML.
Upvotes: 5
Views: 9039
Reputation: 7189
It certainly is possible. I assume that you already have a way of getting the count of the items in the ListView so here's how to convert that number to a boolean value in XAML.
What you need, is a custom implementation of the IValueConverter interface. It can take a value provided by the binding and convert it to something else and back if needed.
In your case, you want to take an integer and return a boolean. If the value is zero, you'll return true and otherwise false.
public class CountToBoolenConverter : IValueConverter
{
public object Convert (object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value != 0;
}
public object ConvertBack (object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException ();
}
}
Next, you'll need to define the namespace in the XAML. On top of the file you should add something like this:
xmlns:local="clr-namespace:YourNameSpace;assembly=YourAssembly"
Add the converter to the page resources just after the opening <ContentPage>
tag (or whatever type of page you have):
<ContentPage>
<ContentPage.Resources>
<ResourceDictionary>
<CountToBoolenConverter x:Key="countToBoolean" />
</ResourceDictionary>
</ContentPage.Resources>
<!-- Rest of the page -->
And then finally use the converter to set the IsVisible property to your Label:
<Label IsVisible="{Binding ItemCount, Converter={StaticResource countToBoolean}}">
ItemCount is an integer property in your viewmodel and it should contain the count of the ListView items. You probably already have a way of loading a collection of items for the ListView so it should be trivial to figure out how this property should be done.
Upvotes: 4
Reputation: 1035
Try this:
XAML
<StackLayout>
<Label Text="Welcome to Xamarin Forms!" IsVisible="{Binding ShowLabel}">
</Label>
<ListView x:Name="TheListView" />
<Button x:Name="btnAddItem" Text="Add an item" Clicked="btnAddItem_Clicked" />
</StackLayout>
public partial class MainPage : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<string> _items = new ObservableCollection<string>();
public bool ShowLabel
{
get
{
return !(Items.Count > 0);
}
}
public ObservableCollection<string> Items
{
get { return _items; }
set
{
_items = value;
}
}
public MainPage()
{
InitializeComponent();
TheListView.ItemsSource = _items;
BindingContext = this;
}
private void btnAddItem_Clicked(object sender, EventArgs e)
{
Items.Add("Add a item");
NotifyPropertyChanged("ShowLabel");
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}}
Upvotes: 0
Reputation: 4763
You can do it purely in XAML using a DataTrigger:
<?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="ListViewTriggerToHideLabel.MainPage">
<StackLayout>
<Label Text="Welcome to Xamarin Forms!" IsVisible="False">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Source={x:Reference TheListView}, Path=ItemsSource.Count}"
Value="0">
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</Label.Triggers>
</Label>
<ListView x:Name="TheListView" />
<Button Text="Add an item" Clicked="Button_OnClicked" />
</StackLayout>
</ContentPage>
The code-behind to handle button clicks and initialise the list content (I normally use data binding, but for simplicity in the example I'm using code-behind):
using System;
using System.Collections.ObjectModel;
using Xamarin.Forms;
namespace ListViewTriggerToHideLabel {
public partial class MainPage : ContentPage {
private readonly ObservableCollection<string> _items = new ObservableCollection<string>();
public MainPage() {
InitializeComponent();
TheListView.ItemsSource = _items;
}
private void Button_OnClicked(object sender, EventArgs e) {
_items.Add("Ouch");
}
}
}
The binding to the Count property works because the ItemsSource is an ObservableCollection.
Upvotes: 11