Data binding to Switch

546 Views Asked by At

I am trying to change bool based on what is on turned on on Switch. Method works in xaml.cs but I would like to do this in ViewModel. Is it posibble? And if yes what should I do?

git:https://github.com/wojblaz/Clicer-Game---final/commits/master/Clicer%20Game

In ViewModel i get an error: "ClassicMode.ModeSelector" is inaccessible due to its protection level.

(Mode selector is name of switch) The same happens without ClassicMode(it is a name of view).

View(Xaml) - ClassicMode:

Is x:Type defined good? `

        <Switch
            x:Name="ModeSelector"
            IsToggled="False"
            Toggled="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:ClassicModelViewModel}}, Path=BindingContext.ModeSelector_ToggledCommand}"
            Grid.Row="1"
            Grid.Column="0"
            HorizontalOptions="Center"/>

`

Xaml.cs - BindingContext `

using Clicer_Game.ViewModels;
using CommunityToolkit.Mvvm.Input;


namespace Clicer_Game.Views;

public partial class ClassicMode : ContentPage
{
    public ClassicMode()
    {
        InitializeComponent();
        BindingContext = new ClassicModelViewModel();
    }

}

`

ViewModel

`


    private bool IsTime;

        [RelayCommand]
        private void ModeSelector_Toggled()
        {
            if (ClassicMode.ModeSelector.IsToggled)
            {
                IsTime = false;
            }
            else
            {
                IsTime = true;
            }
        }

`

What parameter should I use in ModeSelector_Toggled method?

2

There are 2 best solutions below

0
Jianwei Sun - MSFT On BEST ANSWER

You can check this link. It tells about Inaccessible due to its protection level in details. Select ModeSelector and press F12, you should see this:

private global::Microsoft.Maui.Controls.Switch ModeSelector;

The access level is private.

Method 1: You can create a Switch in code, and check this official code. Remember to make Switch's access level public.

Method 2: Write relevant code directly in MainPage.xaml.cs file:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Switch_Toggled(object sender, ToggledEventArgs e)
    {
      if (ModeSelector.IsToggled)
            {
                IsTime = false;
            }
            else
            {
                IsTime = true;
            }
    }
}

ViewModel:

pubulic static bool IsTime;
0
Ishan Sharma On

You can use Command attribute in Switch node. But you cant use Command in Control Events directly. What you can do is use the EventToCommandBehavior behavior given by the CommunityToolkit.Maui NuGet package.

Refer this official .NET MAUI documentation for this: MAUI official docs of EventToCommandBehaviour behavior

For your code you can try the following:

View:

<Switch x:Name="ModeSelector"
    IsToggled="False"
    Grid.Row="1"
    Grid.Column="0"
    HorizontalOptions="Center">
    <Switch.Behaviors>
        <toolkit:EventToCommandBehavior
            EventName="Toggled"
            Command="{Binding ModeSelector_ToggledCommand}" />
    </Switch.Behaviors>
</Switch>

ViewModel:

private bool IsTime;

[RelayCommand]
private void ModeSelector_Toggled()
{
    if (ClassicMode.ModeSelector.IsToggled)
    {
        IsTime = false;
    }
    else
    {
        IsTime = true;
    }
}