vamteusz
vamteusz

Reputation: 113

Binding Listview Item Count to Label Visibility in Xamarin Forms

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

Answers (3)

Timo Salomäki
Timo Salomäki

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

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

Damian
Damian

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

Related Questions