Home > database >  How do I bind a switch to a property in Xamarin in an Android app in a content view?
How do I bind a switch to a property in Xamarin in an Android app in a content view?

Time:05-19

I'm creating my first Android App in VS 2022 with Xamarin and now I have to bind a switch to a label to show the user what on/off means. Multiple times so I made a content view:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:controls="clr-namespace:App1.Controls" x:DataType="controls:SwitchWithText"
             x:Class="App1.Controls.SwitchWithText"
             x:Name="root">
  <ContentView.Content>
      <StackLayout Orientation="Horizontal">
          <Label x:Name="isOkLbl" Text="is not ok" Margin="10"/>
          <Switch x:Name="switch1" IsToggled="{Binding Path=IsToggled}"/>
        </StackLayout>
  </ContentView.Content>
</ContentView>
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace App1.Controls
{
  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class SwitchWithText : ContentView
  {

    public static readonly BindableProperty isToggledProperty = BindableProperty.Create(
      nameof(isToggledProperty),    //name of property
      typeof(bool),                 //type of property
      typeof(SwitchWithText),       //type of owning object
      defaultValue: false,
      propertyChanged: IsToggledChanged);

    public bool IsToggled
    {
      get => (bool)GetValue(isToggledProperty);
      set => SetValue(isToggledProperty, value);
    }

    private static void IsToggledChanged(BindableObject bindable, object oldValue, object newValue)
    {
      var control = (SwitchWithText)bindable;
      if (control != null && control.switch1.IsToggled)
      {
        control.isOkLbl.Text = "is ok";
      }
      else
      {
        control.isOkLbl.Text = "is not ok";
      }
    }
    public SwitchWithText()
    {
      BindingContext = this;
      InitializeComponent();
    }
  }
}

Some stuff is auto complete by Visual Studio 2022 and looks like it'd do what I need but nothing happpens when I toogle the switch. :( Or is there an even better way to do this? I saw pictures of switches with text on it but couldn't find something like that in Xamarin.

CodePudding user response:

Is this your desired outcome? enter image description here

I think what you may want is a value converter class that will take the IsToggled binding and convert it to a string for your label. I posted the working code on GitHub if you'd like to see the functional demo. (I put it directly in the xaml for the ContentPage but of course the same principle will work in a ContentView as in your post.)

using System;
using System.Globalization;
using Xamarin.Forms;

namespace App1
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            BindingContext = this;
            InitializeComponent();
        }
        bool _IsToggled = false;
        public bool IsToggled
        {
            get => _IsToggled;
            set
            {
                if (_IsToggled != value)
                {
                    _IsToggled = value;
                    OnPropertyChanged(nameof(IsToggled));
                }
            }
        }
    }

    /// <summary>
    /// Value converter class
    /// </summary>
    public class BoolToTextConverter : IValueConverter
    {
        public string IfFalse { get; set; }
        public string IfTrue { get; set; }

        public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if ((bool)value)
            {
                return IfTrue;
            }
            else
            {
                return IfFalse;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Then to use the value converter, you would make it a Static Resource in your xaml like this:

<?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:app1="clr-namespace:App1"
             x:Class="App1.MainPage">

    <ContentPage.Resources>
        <app1:BoolToTextConverter x:Key="SwitchToText"
                                 IfTrue="is ok"
                                 IfFalse="is not ok" />
    </ContentPage.Resources>
    <StackLayout>
        <Label Text="{Binding Path=IsToggled, Converter={StaticResource SwitchToText}}" FontSize="Title" Padding="30,10,30,10"/>
        <Switch x:Name="switch1"
                IsToggled="{Binding Path=IsToggled}" />
    </StackLayout>

</ContentPage>

So my suggestion is to try a Value Converter to do what you want.

  • Related