0
votes

I've got a label that I want to bind to a boolean property (HasNotifications). However, when the property is false, the label stays visible. If I set the IsVisible property to false in the XAML, the label isn't visible so the issue appears to be with the binding.

XAML:

<AbsoluteLayout
    HorizontalOptions="FillAndExpand"
    VerticalOptions="FillAndExpand">

    <Grid
        HorizontalOptions="FillAndExpand"
        VerticalOptions="FillAndExpand"
        AbsoluteLayout.LayoutFlags="All"
        AbsoluteLayout.LayoutBounds="0,0,1,1">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Label 
            Text="Title" 
            HorizontalOptions="Center"
            VerticalOptions="Center"
            TextColor="White"
            FontSize="Large"
            FontAttributes="Bold"
            Margin="5"
            BindingContext="{x:Reference DashboardPageView}"
            Grid.Row="0" />

        <Label 
            Text="Notifications" 
            HorizontalOptions="Start"
            VerticalOptions="Center"
            TextColor="White"
            FontSize="Medium"
            FontAttributes="Bold"
            Margin="3"
            BindingContext="{x:Reference DashboardPageView}"
            IsVisible="{Binding HasNotifications}"
            Grid.Row="1" />
    </Grid>
</AbsoluteLayout>

My viewmodel:

public bool HasNotifications
{
    get => this.hasNotifications;
    set => this.SetProperty(ref this.hasNotifications, value);
}
1
are you sure your BindingContext is set correctly? Does your VM implement INotifyPropertyChanged?Jason
@Jason I believe so. The viewmodel also contains an ObservableCollection that I bind to a ListView's ItemsSource's property and that appears okay.Bhav
why are you having to specify a separate BindingContext for the two Labels? Can you try binding HasNotifications to the Label's Text property to verify that it is working like you expect?Jason

1 Answers

2
votes

I don't think you have set the correct BindingContext. The HasNotifications is a property of your ViewModel while the BindingContext you set to your label is DashboardPageView.

I wrote a simple demo and hope you can get some idea from it:

In xaml:

<Grid
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Label 
    Text="Title" 
    HorizontalOptions="Center"
    VerticalOptions="Center"
    TextColor="Black"
    FontSize="Large"
    FontAttributes="Bold"
    Margin="5"
    Grid.Row="0" />

    <Label 
    Text="Notifications" 
    HorizontalOptions="Start"
    VerticalOptions="Center"
    TextColor="Black"
    FontSize="Medium"
    FontAttributes="Bold"
    Margin="3"
    IsVisible="{Binding HasNotifications}"
    Grid.Row="1" />

    <Button Text="change HasNotifications" Clicked="Button_Clicked" Grid.Row="2"/>
    
</Grid>

In cs:

public partial class MainPage : ContentPage
{

    ViewModel myViewModel;
    public MainPage()
    {
        InitializeComponent();

        myViewModel = new ViewModel();

        BindingContext = myViewModel;
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        myViewModel.HasNotifications = !myViewModel.HasNotifications;
    }
}

public class ViewModel : INotifyPropertyChanged
{
    bool _HasNotifications;

    public event PropertyChangedEventHandler PropertyChanged;

    public ViewModel()
    {

    }

    public bool HasNotifications
    {
        set
        {
            if (_HasNotifications != value)
            {
                _HasNotifications = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("HasNotifications"));
                }
            }
        }
        get
        {
            return _HasNotifications;
        }
    }
}

Feel free to ask me any question if you have.